Skip to content
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
fdfd3e2
Added extended signing key support for cip8
theeldermillenial Oct 6, 2023
01230ac
Fixed unused imports, flake8 checks pass.
theeldermillenial Oct 6, 2023
143e843
Fixed mypy error for overloaded variable
theeldermillenial Oct 11, 2023
049c6bf
Remove extraneous parameter for verify
theeldermillenial Oct 18, 2023
434a163
Merge branch 'main' of https://github.com/Python-Cardano/pycardano in…
theeldermillenial Nov 3, 2023
1bf3f81
Added ByteString to _restored_typed_primitive
theeldermillenial Nov 3, 2023
67add7a
Added type checking
theeldermillenial Nov 3, 2023
f0644e7
Merge pull request #1 from theeldermillenial/bugfix/bytestring
theeldermillenial Nov 3, 2023
1edb549
Merge branch 'main' of https://github.com/Python-Cardano/pycardano
theeldermillenial Jan 10, 2024
2424c64
Merge branch 'main' of https://github.com/Python-Cardano/pycardano
theeldermillenial Mar 12, 2024
971237a
Added support for fixed vs indefinite list on cbor decoding
theeldermillenial Mar 14, 2024
e2a1c9d
Fixed bug in verification key witness set deserialization
theeldermillenial Mar 15, 2024
af0c665
Fix type errors
nielstron Mar 18, 2024
f3786f1
Fix types
nielstron Mar 18, 2024
df356ed
Install setuptools
nielstron Mar 18, 2024
639cc97
Fix main.yml
nielstron Mar 18, 2024
03f653d
Revert "Fix main.yml"
nielstron Mar 18, 2024
8fca0f3
Revert "Install setuptools"
nielstron Mar 18, 2024
2e0cddd
Add setuptools to dev dependencies
nielstron Mar 18, 2024
c9a2d85
Add noqa
nielstron Mar 18, 2024
cfb7f2a
Added catch for indefinitelist on deserialization
theeldermillenial Apr 10, 2024
15c806d
Merge branch 'main' of https://github.com/python-cardano/pycardano in…
theeldermillenial Jul 12, 2024
996de30
Passing tests and CI checks
theeldermillenial Jul 12, 2024
dec33a8
Added RawPlutusData to PlutusData primitive types
theeldermillenial Jul 18, 2024
cccf0fe
Added RawPlutusData to PlutusData primitive types
theeldermillenial Jul 18, 2024
b7756ca
Added unit test for RawPlutusData
theeldermillenial Jul 18, 2024
092595c
Merge branch 'main' of https://github.com/python-cardano/pycardano in…
theeldermillenial Jul 19, 2024
b06c153
Merge branch 'feat/rawplutusdata' of https://github.com/theeldermille…
theeldermillenial Jul 19, 2024
c293704
Merge branch 'chang' of https://github.com/python-cardano/pycardano i…
theeldermillenial Sep 1, 2024
7555d03
Ignore venv
theeldermillenial Sep 1, 2024
5e4b813
Added Conway parameters to blockfrost
theeldermillenial Sep 1, 2024
5ce4d04
Changed Conway range to 0
theeldermillenial Sep 1, 2024
6cb839c
Set range to 10
theeldermillenial Sep 2, 2024
42ce792
Changed range to 1
theeldermillenial Sep 2, 2024
83b17a4
Merge branch 'chang' of https://github.com/python-cardano/pycardano i…
theeldermillenial Sep 2, 2024
3dba36b
Changed redeemers to empty map
theeldermillenial Sep 2, 2024
ea03c63
Refactor Redeemer handling in TransactionWitnessSet
bhatt-deep Sep 11, 2024
7a80ff1
Refactor KupoChainContextExtension in kupo.py
bhatt-deep Sep 13, 2024
176314e
Merge pull request #2 from bhatt-deep/chang
bhatt-deep Sep 13, 2024
0d6dd87
Refactor KupoChainContextExtension in kupo.py
bhatt-deep Sep 13, 2024
32a11cc
Changed ogmios version
theeldermillenial Sep 18, 2024
3fd91d0
Merge branch 'chang' of https://github.com/python-cardano/pycardano i…
theeldermillenial Sep 18, 2024
3785614
Changed ogmios dependency
theeldermillenial Sep 18, 2024
f0c15aa
Merge branch 'chang' of https://github.com/charli3-official/pycardano…
theeldermillenial Sep 18, 2024
7b38ec1
Fixed bug in redeemers
theeldermillenial Sep 19, 2024
3890db8
Merge branch 'chang' of https://github.com/python-cardano/pycardano i…
theeldermillenial Sep 21, 2024
af62b7f
Revert plutus changes
theeldermillenial Sep 21, 2024
9094f5e
Reverted witness changes
theeldermillenial Sep 21, 2024
85b703b
Set empty vkey witness to None when empty
theeldermillenial Sep 22, 2024
fca0337
Set vkey witnesses to None when empty
theeldermillenial Sep 22, 2024
8db56f2
Merge branch 'chang' of https://github.com/theeldermillenial/pycardan…
theeldermillenial Sep 22, 2024
d67acf2
Merge branch 'chang' of https://github.com/python-cardano/pycardano i…
theeldermillenial Sep 22, 2024
f1e3f80
Merge branch 'main' of https://github.com/python-cardano/pycardano in…
theeldermillenial Oct 8, 2024
9938b37
Add path to Ogmios v6 backend
theeldermillenial Nov 16, 2024
f203fc7
Merge branch 'feat/ogmios-path' of https://github.com/theeldermilleni…
theeldermillenial Nov 16, 2024
d76ac04
Reverted change for plutus v2 scripts
theeldermillenial Nov 16, 2024
bc6916b
Merge branch 'feat/ogmios-path' of https://github.com/theeldermilleni…
theeldermillenial Nov 16, 2024
3be8b5e
Merge branch 'main' of https://github.com/python-cardano/pycardano in…
theeldermillenial Dec 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
893 changes: 395 additions & 498 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pycardano/cip/cip8.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ def sign(
OKPKpX: verification_key.payload, # public key
}

signed_message = {
return {
"signature": signed_message,
"key": CoseKey.from_dict(key_to_return).encode().hex(),
}

return signed_message
else:
return signed_message


def verify(
Expand Down
3 changes: 3 additions & 0 deletions pycardano/hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ def __hash__(self):
def payload(self) -> bytes:
return self._payload

def to_shallow_primitive(self) -> bytes:
return self.payload

def to_primitive(self) -> bytes:
return self.payload

Expand Down
8 changes: 4 additions & 4 deletions pycardano/plutus.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class CostModels(DictCBORSerializable):
VALUE_TYPE = dict

def to_shallow_primitive(self) -> dict:
result = {}
result: typing.Dict[Primitive, Primitive] = {}
for language in sorted(self.keys()):
cost_model = self[language]
if language == 0:
Expand Down Expand Up @@ -562,8 +562,8 @@ def __post_init__(self):
"Use pycardano.serialization.ByteString for long bytes."
)

def to_shallow_primitive(self) -> CBORTag:
primitives: Primitive = super().to_shallow_primitive()
def to_shallow_primitive(self) -> CBORTag: # type: ignore
primitives: Primitive = super(PlutusData, self).to_shallow_primitive()
if primitives:
primitives = IndefiniteList(primitives)
tag = get_tag(self.CONSTR_ID)
Expand Down Expand Up @@ -788,7 +788,7 @@ def __deepcopy__(self, memo):
class RawPlutusData(CBORSerializable):
data: RawDatum

def to_primitive(self) -> RawDatum:
def to_primitive(self) -> Primitive:
def _dfs(obj):
if isinstance(obj, list) and obj:
return IndefiniteList([_dfs(item) for item in obj])
Expand Down
75 changes: 64 additions & 11 deletions pycardano/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import re
import typing
from collections import OrderedDict, UserList, defaultdict
from collections.abc import Sequence
from copy import deepcopy
from dataclasses import Field, dataclass, fields
from datetime import datetime
from decimal import Decimal
from functools import wraps
from inspect import isclass
from io import BytesIO
from typing import (
Any,
Callable,
Expand All @@ -24,7 +26,14 @@
get_type_hints,
)

from cbor2 import CBOREncoder, CBORSimpleValue, CBORTag, dumps, loads, undefined
from cbor2 import (
CBORDecoder,
CBOREncoder,
CBORSimpleValue,
CBORTag,
dumps,
)
from cbor2._types import UndefinedType, break_marker
from frozendict import frozendict
from frozenlist import FrozenList
from pprintpp import pformat
Expand Down Expand Up @@ -86,6 +95,7 @@ class RawCBOR:
Primitive = Union[
bytes,
bytearray,
ByteString,
str,
int,
float,
Expand All @@ -98,7 +108,7 @@ class RawCBOR:
dict,
defaultdict,
OrderedDict,
undefined.__class__,
UndefinedType,
datetime,
re.Pattern,
CBORSimpleValue,
Expand All @@ -113,6 +123,7 @@ class RawCBOR:
PRIMITIVE_TYPES = (
bytes,
bytearray,
ByteString,
str,
int,
float,
Expand All @@ -125,7 +136,7 @@ class RawCBOR:
dict,
defaultdict,
OrderedDict,
type(undefined),
UndefinedType,
datetime,
re.Pattern,
CBORSimpleValue,
Expand Down Expand Up @@ -169,6 +180,38 @@ def wrapper(cls, value: Primitive):
CBORBase = TypeVar("CBORBase", bound="CBORSerializable")


class IndefiniteDecoder(CBORDecoder):
def decode_array(self, subtype: int) -> Sequence[Any]:
# Major tag 4
length = self._decode_length(subtype, allow_indefinite=True)
if length is None:
# Indefinite length
items: list = []
if not self._immutable:
self.set_shareable(items)
while True:
value = self._decode()
if value is break_marker:
break
else:
items.append(value)

return IndefiniteList(items)
else:
return super().decode_array(subtype=subtype)

major_decoders: dict[int, Callable[[Any, int], Any]] = {
0: CBORDecoder.decode_uint,
1: CBORDecoder.decode_negint,
2: CBORDecoder.decode_bytestring,
3: CBORDecoder.decode_string,
4: decode_array,
5: CBORDecoder.decode_map,
6: CBORDecoder.decode_semantic,
7: CBORDecoder.decode_special,
}


def default_encoder(
encoder: CBOREncoder, value: Union[CBORSerializable, IndefiniteList]
):
Expand Down Expand Up @@ -235,7 +278,7 @@ class CBORSerializable:
does not refer to itself, which could cause infinite loops.
"""

def to_shallow_primitive(self) -> Primitive:
def to_shallow_primitive(self) -> Union[Primitive, "CBORSerializable"]:
"""
Convert the instance to a CBOR primitive. If the primitive is a container, e.g. list, dict, the type of
its elements could be either a Primitive or a CBORSerializable.
Expand Down Expand Up @@ -479,9 +522,12 @@ def from_cbor(cls, payload: Union[str, bytes]) -> CBORSerializable:
TestParent(3, Test(1, 2))

"""
if type(payload) == str:
if isinstance(payload, str):
payload = bytes.fromhex(payload)
value = loads(payload)

with BytesIO(payload) as fp:
value = IndefiniteDecoder(fp).decode()

return cls.from_primitive(value)

def __repr__(self):
Expand All @@ -503,6 +549,7 @@ def _restore_dataclass_field(

if "object_hook" in f.metadata:
return f.metadata["object_hook"](v)

return _restore_typed_primitive(f.type, v)


Expand All @@ -528,10 +575,14 @@ def _restore_typed_primitive(
raise DeserializeException(
f"List types need exactly one type argument, but got {t_args}"
)
t = t_args[0]
if not isinstance(v, list):
t_subtype = t_args[0]
if not isinstance(v, (list, IndefiniteList)):
raise DeserializeException(f"Expected type list but got {type(v)}")
return IndefiniteList([_restore_typed_primitive(t, w) for w in v])
v_list = [_restore_typed_primitive(t_subtype, w) for w in v]
if t == IndefiniteList:
return IndefiniteList(v_list)
else:
return v_list
elif isclass(t) and t == ByteString:
if not isinstance(v, bytes):
raise DeserializeException(f"Expected type bytes but got {type(v)}")
Expand Down Expand Up @@ -657,8 +708,10 @@ def to_shallow_primitive(self) -> List[Primitive]:
return primitives

@classmethod
@limit_primitive_type(list, tuple)
def from_primitive(cls: Type[ArrayBase], values: Union[list, tuple]) -> ArrayBase:
@limit_primitive_type(list, tuple, IndefiniteList)
def from_primitive(
cls: Type[ArrayBase], values: Union[list, tuple, IndefiniteList]
) -> ArrayBase:
"""Restore a primitive value to its original class type.

Args:
Expand Down
16 changes: 9 additions & 7 deletions pycardano/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from copy import deepcopy
from dataclasses import dataclass, field
from pprint import pformat
from typing import Any, Callable, List, Optional, Type, Union
from typing import Any, Callable, List, Optional, Type, Union, cast

import cbor2
from cbor2 import CBORTag
Expand Down Expand Up @@ -281,7 +281,7 @@ def from_primitive(cls: Type[_Script], values: List[Primitive]) -> _Script:
class _DatumOption(ArrayCBORSerializable):
_TYPE: int = field(init=False, default=0)

datum: Union[DatumHash, Any]
datum: Union[DatumHash, Datum]

def __post_init__(self):
if isinstance(self.datum, DatumHash):
Expand All @@ -290,10 +290,10 @@ def __post_init__(self):
self._TYPE = 1

def to_shallow_primitive(self) -> List[Primitive]:
if self._TYPE == 1:
data = CBORTag(24, cbor2.dumps(self.datum, default=default_encoder))
if self._TYPE == 0:
data: Primitive = cast(DatumHash, self.datum).to_shallow_primitive()
else:
data = self.datum
data = CBORTag(24, cbor2.dumps(self.datum, default=default_encoder))
return [self._TYPE, data]

@classmethod
Expand Down Expand Up @@ -402,8 +402,10 @@ def lovelace(self) -> int:
def to_primitive(self) -> Primitive:
if self.datum or self.script or self.post_alonzo:
datum = (
_DatumOption(self.datum_hash or self.datum)
if self.datum is not None or self.datum_hash is not None
_DatumOption(self.datum_hash)
if self.datum_hash is not None
else _DatumOption(self.datum)
if self.datum is not None
else None
)
script_ref = (
Expand Down
10 changes: 5 additions & 5 deletions pycardano/txbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1181,10 +1181,10 @@ def build(
)
raise UTxOSelectionException(
f"All UTxO selectors failed.\n"
f"Requested output:\n {requested_amount} \n"
f"Pre-selected inputs:\n {selected_amount} \n"
f"Additional UTxO pool:\n {additional_utxo_pool} \n"
f"Unfulfilled amount:\n {diff}"
f"Requested output:\n {requested_amount} \n" # noqa: E231
f"Pre-selected inputs:\n {selected_amount} \n" # noqa: E231
f"Additional UTxO pool:\n {additional_utxo_pool} \n" # noqa: E231
f"Unfulfilled amount:\n {diff}" # noqa: E231
)

selected_utxos.sort(
Expand Down Expand Up @@ -1317,7 +1317,7 @@ def _update_execution_units(
r.tag is not None
), "Expected tag of redeemer to be set, but found None"
tagname = r.tag.name.lower()
key = f"{tagname}:{r.index}"
key = f"{tagname}:{r.index}" # noqa: E231
if (
key not in estimated_execution_units
or estimated_execution_units[key] is None
Expand Down
19 changes: 14 additions & 5 deletions pycardano/witness.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Transaction witness."""

from __future__ import annotations

from dataclasses import dataclass, field
Expand Down Expand Up @@ -86,27 +87,35 @@ def from_primitive(
def _get_vkey_witnesses(data: Any):
return (
[VerificationKeyWitness.from_primitive(witness) for witness in data]
if data
if data is not None
else None
)

def _get_native_scripts(data: Any):
return (
[NativeScript.from_primitive(script) for script in data]
if data
if data is not None
else None
)

def _get_plutus_v1_scripts(data: Any):
return [PlutusV1Script(script) for script in data] if data else None
return (
[PlutusV1Script(script) for script in data]
if data is not None
else None
)

def _get_plutus_v2_scripts(data: Any):
return [PlutusV2Script(script) for script in data] if data else None
return (
[PlutusV2Script(script) for script in data]
if data is not None
else None
)

def _get_redeemers(data: Any):
return (
[Redeemer.from_primitive(redeemer) for redeemer in data]
if data
if data is not None
else None
)

Expand Down
14 changes: 5 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ repository = "https://github.com/Python-Cardano/pycardano"
license = "MIT"

[tool.poetry.dependencies]
python = "^3.7"
python = "^3.8"
PyNaCl = "^1.5.0"
cbor2 = "^5.4.3"
cbor2 = { git = "https://github.com/theeldermillenial/cbor2", branch = "feat/local-decoders" }
typeguard = "^2.13.3"
blockfrost-python = "0.5.3"
websocket-client = "^1.4.1"
Expand All @@ -50,6 +50,7 @@ retry = "^0.9.2"
Flask = "^2.0.3"
pytest-xdist = "^3.5.0"
mypy = "^1.0.1"
setuptools = {version = "^69.2.0", python = "^3.7"}

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand All @@ -59,10 +60,7 @@ build-backend = "poetry.core.masonry.api"
[tool.pytest.ini_options]
addopts = "--doctest-modules --ignore=examples --ignore=integration-test --ignore=test/resources/haskell"
minversion = "6.0"
markers = [
"post_alonzo",
"single"
]
markers = ["post_alonzo", "single"]

[tool.isort]
profile = "black"
Expand All @@ -71,6 +69,4 @@ profile = "black"
ignore_missing_imports = true
disable_error_code = ["str-bytes-safe"]
python_version = 3.7
exclude = [
'^pycardano/crypto/bech32.py$',
]
exclude = ['^pycardano/crypto/bech32.py$']
Loading