algokit-utils 3.0.0b8__py3-none-any.whl → 3.0.0b10__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.
Potentially problematic release.
This version of algokit-utils might be problematic. Click here for more details.
- algokit_utils/applications/app_client.py +5 -0
- algokit_utils/applications/app_spec/arc56.py +40 -15
- algokit_utils/transactions/transaction_composer.py +48 -34
- {algokit_utils-3.0.0b8.dist-info → algokit_utils-3.0.0b10.dist-info}/METADATA +1 -1
- {algokit_utils-3.0.0b8.dist-info → algokit_utils-3.0.0b10.dist-info}/RECORD +7 -7
- {algokit_utils-3.0.0b8.dist-info → algokit_utils-3.0.0b10.dist-info}/LICENSE +0 -0
- {algokit_utils-3.0.0b8.dist-info → algokit_utils-3.0.0b10.dist-info}/WHEEL +0 -0
|
@@ -1900,6 +1900,11 @@ class AppClient:
|
|
|
1900
1900
|
method = self._app_spec.get_arc56_method(method_name_or_signature)
|
|
1901
1901
|
result: list[ABIValue | ABIStruct | AppMethodCallTransactionArgument | None] = []
|
|
1902
1902
|
|
|
1903
|
+
if args and len(method.args) < len(args):
|
|
1904
|
+
raise ValueError(
|
|
1905
|
+
f"Unexpected arg at position {len(method.args)}. {method.name} only expects {len(method.args)} args"
|
|
1906
|
+
)
|
|
1907
|
+
|
|
1903
1908
|
for i, method_arg in enumerate(method.args):
|
|
1904
1909
|
arg_value = args[i] if args and i < len(args) else None
|
|
1905
1910
|
|
|
@@ -672,22 +672,47 @@ class SourceInfoModel:
|
|
|
672
672
|
return SourceInfoModel(**data)
|
|
673
673
|
|
|
674
674
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
675
|
+
# constants that define which parent keys mark a region whose inner keys should remain unchanged.
|
|
676
|
+
PROTECTED_TOP_DICTS = {"networks", "scratch_variables", "template_variables", "structs"}
|
|
677
|
+
STATE_PROTECTED_PARENTS = {"keys", "maps"}
|
|
678
|
+
STATE_PROTECTED_CHILDREN = {"global", "local", "box"}
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
def _is_protected_path(path: tuple[str, ...]) -> bool:
|
|
682
|
+
"""
|
|
683
|
+
Return True if the current recursion path indicates that we are inside a protected dictionary,
|
|
684
|
+
meaning that the keys should be left unchanged.
|
|
685
|
+
"""
|
|
686
|
+
return (len(path) >= 2 and path[-2] in STATE_PROTECTED_PARENTS and path[-1] in STATE_PROTECTED_CHILDREN) or ( # noqa: PLR2004
|
|
687
|
+
len(path) >= 1 and path[-1] in PROTECTED_TOP_DICTS
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
def _dict_keys_to_snake_case(value: Any, path: tuple[str, ...] = ()) -> Any: # noqa: ANN401
|
|
692
|
+
"""Recursively convert dictionary keys to snake_case except in protected sections.
|
|
693
|
+
|
|
694
|
+
A dictionary is not converted if it is directly under:
|
|
695
|
+
- keys/maps sections ("global", "local", "box")
|
|
696
|
+
- or one of the top-level keys ("networks", "scratchVariables", "templateVariables", "structs")
|
|
697
|
+
(Note that once converted the parent key names become snake_case.)
|
|
698
|
+
"""
|
|
699
|
+
import re
|
|
700
|
+
|
|
678
701
|
def camel_to_snake(s: str) -> str:
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
702
|
+
# Use a regular expression to insert an underscore before capital letters (except at start).
|
|
703
|
+
return re.sub(r"(?<!^)(?=[A-Z])", "_", s).lower()
|
|
704
|
+
|
|
705
|
+
if isinstance(value, dict):
|
|
706
|
+
protected = _is_protected_path(path)
|
|
707
|
+
new_dict = {}
|
|
708
|
+
for key, val in value.items():
|
|
709
|
+
new_key = key if protected else camel_to_snake(key)
|
|
710
|
+
new_dict[new_key] = _dict_keys_to_snake_case(val, (*path, new_key))
|
|
711
|
+
return new_dict
|
|
712
|
+
elif isinstance(value, list):
|
|
713
|
+
return [_dict_keys_to_snake_case(item, path) for item in value]
|
|
714
|
+
else:
|
|
715
|
+
return value
|
|
691
716
|
|
|
692
717
|
|
|
693
718
|
class _Arc32ToArc56Converter:
|
|
@@ -591,9 +591,27 @@ class SendAtomicTransactionComposerResults:
|
|
|
591
591
|
simulate_response: dict[str, Any] | None = None
|
|
592
592
|
|
|
593
593
|
|
|
594
|
+
class UnnamedResourcesAccessed:
|
|
595
|
+
"""Information about unnamed resource access."""
|
|
596
|
+
|
|
597
|
+
def __init__(self, resources_accessed: dict[str, Any] | None = None):
|
|
598
|
+
resources = resources_accessed or {}
|
|
599
|
+
|
|
600
|
+
if not isinstance(resources, dict):
|
|
601
|
+
raise TypeError(f"Expected dictionary object, got {type(resources_accessed)}")
|
|
602
|
+
|
|
603
|
+
self.accounts: list[str] | None = resources.get("accounts", None)
|
|
604
|
+
self.app_locals: list[dict[str, Any]] | None = resources.get("app-locals", None)
|
|
605
|
+
self.apps: list[int] | None = resources.get("apps", None)
|
|
606
|
+
self.asset_holdings: list[dict[str, Any]] | None = resources.get("asset-holdings", None)
|
|
607
|
+
self.assets: list[int] | None = resources.get("assets", None)
|
|
608
|
+
self.boxes: list[dict[str, Any]] | None = resources.get("boxes", None)
|
|
609
|
+
self.extra_box_refs: int | None = resources.get("extra-box-refs", None)
|
|
610
|
+
|
|
611
|
+
|
|
594
612
|
@dataclass
|
|
595
613
|
class ExecutionInfoTxn:
|
|
596
|
-
unnamed_resources_accessed:
|
|
614
|
+
unnamed_resources_accessed: UnnamedResourcesAccessed | None = None
|
|
597
615
|
required_fee_delta: int = 0
|
|
598
616
|
|
|
599
617
|
|
|
@@ -601,7 +619,7 @@ class ExecutionInfoTxn:
|
|
|
601
619
|
class ExecutionInfo:
|
|
602
620
|
"""Information about transaction execution from simulation."""
|
|
603
621
|
|
|
604
|
-
group_unnamed_resources_accessed:
|
|
622
|
+
group_unnamed_resources_accessed: UnnamedResourcesAccessed | None = None
|
|
605
623
|
txns: list[ExecutionInfoTxn] | None = None
|
|
606
624
|
|
|
607
625
|
|
|
@@ -706,7 +724,7 @@ def _get_group_execution_info( # noqa: C901, PLR0912
|
|
|
706
724
|
)
|
|
707
725
|
failed_at = group_response.get("failed-at", [0])[0]
|
|
708
726
|
raise ValueError(
|
|
709
|
-
f"Error
|
|
727
|
+
f"Error resolving execution info via simulate in transaction {failed_at}: "
|
|
710
728
|
f"{group_response['failure-message']}"
|
|
711
729
|
)
|
|
712
730
|
|
|
@@ -745,7 +763,7 @@ def _get_group_execution_info( # noqa: C901, PLR0912
|
|
|
745
763
|
|
|
746
764
|
txn_results.append(
|
|
747
765
|
ExecutionInfoTxn(
|
|
748
|
-
unnamed_resources_accessed=txn_result_raw.get("unnamed-resources-accessed")
|
|
766
|
+
unnamed_resources_accessed=UnnamedResourcesAccessed(txn_result_raw.get("unnamed-resources-accessed"))
|
|
749
767
|
if populate_app_call_resources
|
|
750
768
|
else None,
|
|
751
769
|
required_fee_delta=required_fee_delta,
|
|
@@ -753,7 +771,7 @@ def _get_group_execution_info( # noqa: C901, PLR0912
|
|
|
753
771
|
)
|
|
754
772
|
|
|
755
773
|
return ExecutionInfo(
|
|
756
|
-
group_unnamed_resources_accessed=group_response.get("unnamed-resources-accessed")
|
|
774
|
+
group_unnamed_resources_accessed=UnnamedResourcesAccessed(group_response.get("unnamed-resources-accessed"))
|
|
757
775
|
if populate_app_call_resources
|
|
758
776
|
else None,
|
|
759
777
|
txns=txn_results,
|
|
@@ -1052,11 +1070,11 @@ def prepare_group_for_sending( # noqa: C901, PLR0912, PLR0915
|
|
|
1052
1070
|
resources = txn_info.unnamed_resources_accessed
|
|
1053
1071
|
if resources and is_app_txn:
|
|
1054
1072
|
app_txn = group[i].txn
|
|
1055
|
-
if resources.
|
|
1073
|
+
if resources.boxes or resources.extra_box_refs:
|
|
1056
1074
|
raise ValueError("Unexpected boxes at transaction level")
|
|
1057
|
-
if resources.
|
|
1075
|
+
if resources.app_locals:
|
|
1058
1076
|
raise ValueError("Unexpected app local at transaction level")
|
|
1059
|
-
if resources.
|
|
1077
|
+
if resources.asset_holdings:
|
|
1060
1078
|
raise ValueError("Unexpected asset holding at transaction level")
|
|
1061
1079
|
|
|
1062
1080
|
# Update application call fields
|
|
@@ -1066,10 +1084,10 @@ def prepare_group_for_sending( # noqa: C901, PLR0912, PLR0915
|
|
|
1066
1084
|
boxes = list(getattr(app_txn, "boxes", []) or [])
|
|
1067
1085
|
|
|
1068
1086
|
# Add new resources
|
|
1069
|
-
accounts.extend(resources.
|
|
1070
|
-
foreign_apps.extend(resources.
|
|
1071
|
-
foreign_assets.extend(resources.
|
|
1072
|
-
boxes.extend(resources.
|
|
1087
|
+
accounts.extend(resources.accounts or [])
|
|
1088
|
+
foreign_apps.extend(resources.apps or [])
|
|
1089
|
+
foreign_assets.extend(resources.assets or [])
|
|
1090
|
+
boxes.extend(resources.boxes or [])
|
|
1073
1091
|
|
|
1074
1092
|
# Validate limits
|
|
1075
1093
|
if len(accounts) > MAX_APP_CALL_ACCOUNT_REFERENCES:
|
|
@@ -1113,45 +1131,41 @@ def prepare_group_for_sending( # noqa: C901, PLR0912, PLR0915
|
|
|
1113
1131
|
group_resources = execution_info.group_unnamed_resources_accessed
|
|
1114
1132
|
if group_resources:
|
|
1115
1133
|
# Handle cross-reference resources first
|
|
1116
|
-
for app_local in group_resources.
|
|
1134
|
+
for app_local in group_resources.app_locals or []:
|
|
1117
1135
|
populate_group_resource(group, app_local, "appLocal")
|
|
1118
1136
|
# Remove processed resources
|
|
1119
|
-
if
|
|
1120
|
-
group_resources
|
|
1121
|
-
|
|
1122
|
-
]
|
|
1123
|
-
if "apps" in group_resources:
|
|
1124
|
-
group_resources["apps"] = [app for app in group_resources["apps"] if int(app) != int(app_local["app"])]
|
|
1137
|
+
if group_resources.accounts:
|
|
1138
|
+
group_resources.accounts = [acc for acc in group_resources.accounts if acc != app_local["account"]]
|
|
1139
|
+
if group_resources.apps:
|
|
1140
|
+
group_resources.apps = [app for app in group_resources.apps if int(app) != int(app_local["app"])]
|
|
1125
1141
|
|
|
1126
|
-
for asset_holding in group_resources.
|
|
1142
|
+
for asset_holding in group_resources.asset_holdings or []:
|
|
1127
1143
|
populate_group_resource(group, asset_holding, "assetHolding")
|
|
1128
1144
|
# Remove processed resources
|
|
1129
|
-
if
|
|
1130
|
-
group_resources
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
group_resources["assets"] = [
|
|
1135
|
-
asset for asset in group_resources["assets"] if int(asset) != int(asset_holding["asset"])
|
|
1145
|
+
if group_resources.accounts:
|
|
1146
|
+
group_resources.accounts = [acc for acc in group_resources.accounts if acc != asset_holding["account"]]
|
|
1147
|
+
if group_resources.assets:
|
|
1148
|
+
group_resources.assets = [
|
|
1149
|
+
asset for asset in group_resources.assets if int(asset) != int(asset_holding["asset"])
|
|
1136
1150
|
]
|
|
1137
1151
|
|
|
1138
1152
|
# Handle remaining resources
|
|
1139
|
-
for account in group_resources.
|
|
1153
|
+
for account in group_resources.accounts or []:
|
|
1140
1154
|
populate_group_resource(group, account, "account")
|
|
1141
1155
|
|
|
1142
|
-
for box in group_resources.
|
|
1156
|
+
for box in group_resources.boxes or []:
|
|
1143
1157
|
populate_group_resource(group, box, "box")
|
|
1144
|
-
if
|
|
1145
|
-
group_resources
|
|
1158
|
+
if group_resources.apps:
|
|
1159
|
+
group_resources.apps = [app for app in group_resources.apps if int(app) != int(box["app"])]
|
|
1146
1160
|
|
|
1147
|
-
for asset in group_resources.
|
|
1161
|
+
for asset in group_resources.assets or []:
|
|
1148
1162
|
populate_group_resource(group, asset, "asset")
|
|
1149
1163
|
|
|
1150
|
-
for app in group_resources.
|
|
1164
|
+
for app in group_resources.apps or []:
|
|
1151
1165
|
populate_group_resource(group, app, "app")
|
|
1152
1166
|
|
|
1153
1167
|
# Handle extra box references
|
|
1154
|
-
extra_box_refs = group_resources.
|
|
1168
|
+
extra_box_refs = group_resources.extra_box_refs or 0
|
|
1155
1169
|
for _ in range(extra_box_refs):
|
|
1156
1170
|
populate_group_resource(group, {"app": 0, "name": ""}, "box")
|
|
1157
1171
|
|
|
@@ -21,13 +21,13 @@ algokit_utils/application_client.py,sha256=5UIxXIBjukjRyjZPCeXmaNlAftbb3TziV7EfB
|
|
|
21
21
|
algokit_utils/application_specification.py,sha256=-ZM13Qv-AcLmwudJCq8xGPoWLvAvKBICgAdHeFozKbY,1416
|
|
22
22
|
algokit_utils/applications/__init__.py,sha256=NGjhpBeExsQZOAYCT2QUFag1xuKoFiX-Ux5SR2GNzd8,452
|
|
23
23
|
algokit_utils/applications/abi.py,sha256=IhrEUdg2kDzR4iU5_FzUDjlMIHO7Rfe-ibJ6z9CMUq8,10260
|
|
24
|
-
algokit_utils/applications/app_client.py,sha256=
|
|
24
|
+
algokit_utils/applications/app_client.py,sha256=TGMngl7BNLvMlMt3lsREEQrI0C1-jl4IhYqVNr2oG7g,85191
|
|
25
25
|
algokit_utils/applications/app_deployer.py,sha256=MD7RIvh6Z6dFr9sx8dP5nP1DzSEbwz-vX-Exz_CwoN4,24740
|
|
26
26
|
algokit_utils/applications/app_factory.py,sha256=wljyXuXWaMc3KJkDeACJ5XVEfIsVxeSXqdGTJ9p3tJQ,33425
|
|
27
27
|
algokit_utils/applications/app_manager.py,sha256=EA1uRtmvPVAdKi1I5HSCpHjIDgLN7eZcEPT0Cj3C7fU,17661
|
|
28
28
|
algokit_utils/applications/app_spec/__init__.py,sha256=HtjAhAqHNFml9WbRKGmhJnwyJeW8AztPRO_BriQ84vs,140
|
|
29
29
|
algokit_utils/applications/app_spec/arc32.py,sha256=8MMGUopPzkWq48rl5sYbc2Awf-RKnxSX8F0P0UibK5M,7523
|
|
30
|
-
algokit_utils/applications/app_spec/arc56.py,sha256=
|
|
30
|
+
algokit_utils/applications/app_spec/arc56.py,sha256=LS-EA4lYNe6kCR9z6lvB8tGLV-t4qLe3Rttg2Wg5z7Y,32984
|
|
31
31
|
algokit_utils/applications/enums.py,sha256=1MUBrPW9v0-OZk6jsa5rqSEEpC-z-6QAQIs9G7pLn1I,1257
|
|
32
32
|
algokit_utils/asset.py,sha256=ZnNo_MsDGPb8UTPxi7cmIZpbrT0x0xZjblHP01pDAC0,874
|
|
33
33
|
algokit_utils/assets/__init__.py,sha256=6igogt0eo0TEae6-rO9qPsmlrKkbnkq3aV8wtePX3yk,63
|
|
@@ -61,10 +61,10 @@ algokit_utils/protocols/account.py,sha256=CowaVY7ErBP84TWBHNvBjkZy18whPb8HIlMZtJ
|
|
|
61
61
|
algokit_utils/protocols/typed_clients.py,sha256=UrQrHbN2SvS8pEFJ8JQodvouoWeBrQOQGZGyBQx1KLM,3322
|
|
62
62
|
algokit_utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
algokit_utils/transactions/__init__.py,sha256=7fYF3m6DyOGzbV36MT5svo0wSkj9AIz496kWgIWSAlk,225
|
|
64
|
-
algokit_utils/transactions/transaction_composer.py,sha256=
|
|
64
|
+
algokit_utils/transactions/transaction_composer.py,sha256=S9GrGDCTg0JJa4HbcTVbGAsV_qAHW2xWNiT9olo6_tk,96058
|
|
65
65
|
algokit_utils/transactions/transaction_creator.py,sha256=A1YHeGC2EkR2V0HPYJiXVOAEIrfjBW2KVyYgi3exm4E,6167
|
|
66
66
|
algokit_utils/transactions/transaction_sender.py,sha256=uQmHElJgUIxLXfdklMNoabjQQzUku8CFP82wwhfr44E,22769
|
|
67
|
-
algokit_utils-3.0.
|
|
68
|
-
algokit_utils-3.0.
|
|
69
|
-
algokit_utils-3.0.
|
|
70
|
-
algokit_utils-3.0.
|
|
67
|
+
algokit_utils-3.0.0b10.dist-info/LICENSE,sha256=J5i7U1Q9Q2c7saUzlvFRmrCCFhQyXb5Juz_LO5omNUw,1076
|
|
68
|
+
algokit_utils-3.0.0b10.dist-info/METADATA,sha256=uSusbjVEq43dNLdD_nfzk-AvBleVdY-TgCxCVOvbGC0,2421
|
|
69
|
+
algokit_utils-3.0.0b10.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
70
|
+
algokit_utils-3.0.0b10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|