algokit-utils 4.1.0b4__py3-none-any.whl → 4.1.0b6__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/__init__.py CHANGED
@@ -9,10 +9,6 @@ For more specific functionality, import directly from the relevant submodules:
9
9
  etc.
10
10
  """
11
11
 
12
- import importlib.util
13
-
14
- _EXPERIMENTAL_DEPENDENCIES_INSTALLED: bool | None = importlib.util.find_spec("algokit_algod_api") is not None
15
-
16
12
  # Core types and utilities that are commonly used
17
13
  from algokit_utils.applications import * # noqa: F403
18
14
  from algokit_utils.assets import * # noqa: F403
@@ -95,6 +95,9 @@ __all__ = [
95
95
  # TEAL opcodes for constant blocks
96
96
  BYTE_CBLOCK = 38 # bytecblock opcode
97
97
  INT_CBLOCK = 32 # intcblock opcode
98
+ MAX_SIMULATE_OPCODE_BUDGET = (
99
+ 20_000 * 16
100
+ ) # https://github.com/algorand/go-algorand/blob/807b29a91c371d225e12b9287c5d56e9b33c4e4c/ledger/simulation/trace.go#L104
98
101
 
99
102
  T = TypeVar("T") # For generic return type in _handle_call_errors
100
103
 
@@ -1183,7 +1186,6 @@ class _TransactionSender:
1183
1186
  :param params: Parameters for the application call including method and transaction options
1184
1187
  :param send_params: Send parameters
1185
1188
  :return: The result of sending or simulating the transaction, including ABI return value if applicable
1186
- :raises ValueError: If the transaction is read-only and `max_fee` is not provided
1187
1189
  """
1188
1190
  is_read_only_call = (
1189
1191
  params.on_complete == algosdk.transaction.OnComplete.NoOpOC or params.on_complete is None
@@ -1194,14 +1196,10 @@ class _TransactionSender:
1194
1196
  readonly_send_params = send_params or SendParams()
1195
1197
 
1196
1198
  # Read-only calls do not require fees to be paid, as they are only simulated on the network.
1197
- # Therefore there is no value in calculating the minimum fee needed for a successful app call with inners.
1198
- # As a a result we only need to send a single simulate call,
1199
- # however to do this successfully we need to ensure fees for the transaction are fully covered using maxFee.
1200
- if readonly_send_params.get("cover_app_call_inner_transaction_fees"):
1201
- if params.max_fee is None:
1202
- raise ValueError(
1203
- "Please provide a `max_fee` for the transaction when `cover_app_call_inner_transaction_fees` is enabled." # noqa: E501
1204
- )
1199
+ # With maximum opcode budget provided, ensure_budget won't create inner transactions,
1200
+ # so fee coverage is no longer a concern for read-only calls.
1201
+ # If max_fee is provided, use it as static_fee for potential benefits.
1202
+ if readonly_send_params.get("cover_app_call_inner_transaction_fees") and params.max_fee is not None:
1205
1203
  readonly_params = replace(readonly_params, static_fee=params.max_fee, extra_fee=None)
1206
1204
 
1207
1205
  method_call_to_simulate = self._algorand.new_group().add_app_call_method_call(
@@ -1215,11 +1213,13 @@ class _TransactionSender:
1215
1213
  skip_signatures=True,
1216
1214
  allow_more_logs=True,
1217
1215
  allow_empty_signatures=True,
1218
- extra_opcode_budget=None,
1216
+ extra_opcode_budget=MAX_SIMULATE_OPCODE_BUDGET,
1219
1217
  exec_trace_config=None,
1220
1218
  simulation_round=None,
1221
1219
  )
1222
1220
  except Exception as e:
1221
+ # For read-only calls with max opcode budget, fee issues should be rare
1222
+ # but we can still provide helpful error message if they occur
1223
1223
  if readonly_send_params.get("cover_app_call_inner_transaction_fees") and "fee too small" in str(e):
1224
1224
  raise ValueError(
1225
1225
  "Fees were too small. You may need to increase the transaction `maxFee`."
@@ -13,7 +13,6 @@ from algosdk.transaction import SuggestedParams
13
13
  from algosdk.v2client.algod import AlgodClient
14
14
  from algosdk.v2client.indexer import IndexerClient
15
15
 
16
- from algokit_utils import _EXPERIMENTAL_DEPENDENCIES_INSTALLED
17
16
  from algokit_utils._legacy_v2.application_specification import ApplicationSpecification
18
17
  from algokit_utils.applications.app_deployer import ApplicationLookup
19
18
  from algokit_utils.applications.app_spec.arc56 import Arc56Contract
@@ -120,12 +119,7 @@ class ClientManager:
120
119
  if clients_or_configs.kmd_config
121
120
  else None,
122
121
  )
123
- if not _EXPERIMENTAL_DEPENDENCIES_INSTALLED:
124
- self._algod = _clients.algod
125
- else:
126
- from algokit_utils.clients._algokit_core_bridge import AlgodClientWithCore
127
-
128
- self._algod = AlgodClientWithCore(_clients.algod) # type: ignore[assignment]
122
+ self._algod = _clients.algod
129
123
  self._indexer = _clients.indexer
130
124
  self._kmd = _clients.kmd
131
125
  self._algorand = algorand_client
@@ -33,7 +33,7 @@ class LogicErrorData(TypedDict):
33
33
  def parse_logic_error(
34
34
  error_str: str,
35
35
  ) -> LogicErrorData | None:
36
- match = re.search(LOGIC_ERROR, error_str, re.DOTALL)
36
+ match = re.match(LOGIC_ERROR, error_str)
37
37
  if match is None:
38
38
  return None
39
39
 
@@ -22,7 +22,6 @@ from algosdk.v2client.algod import AlgodClient
22
22
  from algosdk.v2client.models.simulate_request import SimulateRequest
23
23
  from typing_extensions import deprecated
24
24
 
25
- from algokit_utils import _EXPERIMENTAL_DEPENDENCIES_INSTALLED
26
25
  from algokit_utils.applications.abi import ABIReturn, ABIValue
27
26
  from algokit_utils.applications.app_manager import AppManager
28
27
  from algokit_utils.applications.app_spec.arc56 import Method as Arc56Method
@@ -31,9 +30,6 @@ from algokit_utils.models.state import BoxIdentifier, BoxReference
31
30
  from algokit_utils.models.transaction import SendParams, TransactionWrapper
32
31
  from algokit_utils.protocols.account import TransactionSignerAccountProtocol
33
32
 
34
- if _EXPERIMENTAL_DEPENDENCIES_INSTALLED:
35
- from algokit_utils.transactions._algokit_core_bridge import build_payment_with_core
36
-
37
33
  if TYPE_CHECKING:
38
34
  from collections.abc import Callable
39
35
 
@@ -1865,17 +1861,6 @@ class TransactionComposer:
1865
1861
  )
1866
1862
  except algosdk.error.AlgodHTTPError as e:
1867
1863
  raise Exception(f"Transaction failed: {e}") from e
1868
- # We need this code to handle separately an exception thrown by the experimental AlgoKit Algod Client.
1869
- # However, we can't just import the dependency (as it may not be there) and
1870
- # we still need to re-throw the exception in all other cases.
1871
- except Exception as e:
1872
- if _EXPERIMENTAL_DEPENDENCIES_INSTALLED:
1873
- from algokit_algod_api.exceptions import BadRequestException
1874
-
1875
- if isinstance(e, BadRequestException):
1876
- raise Exception(f"Transaction failed: {e}") from e
1877
- raise e
1878
- raise e
1879
1864
 
1880
1865
  def _handle_simulate_error(self, simulate_response: SimulateAtomicTransactionResponse) -> None:
1881
1866
  # const failedGroup = simulateResponse?.txnGroups[0]
@@ -2265,10 +2250,7 @@ class TransactionComposer:
2265
2250
  "close_remainder_to": params.close_remainder_to,
2266
2251
  }
2267
2252
 
2268
- if _EXPERIMENTAL_DEPENDENCIES_INSTALLED:
2269
- return self._common_txn_build_step(lambda x: build_payment_with_core(**x), params, txn_params)
2270
- else:
2271
- return self._common_txn_build_step(lambda x: algosdk.transaction.PaymentTxn(**x), params, txn_params)
2253
+ return self._common_txn_build_step(lambda x: algosdk.transaction.PaymentTxn(**x), params, txn_params)
2272
2254
 
2273
2255
  def _build_asset_create(
2274
2256
  self, params: AssetCreateParams, suggested_params: algosdk.transaction.SuggestedParams
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: algokit-utils
3
- Version: 4.1.0b4
3
+ Version: 4.1.0b6
4
4
  Summary: Utilities for Algorand development for use by AlgoKit
5
5
  License: MIT
6
6
  Author: Algorand Foundation
@@ -1,4 +1,4 @@
1
- algokit_utils/__init__.py,sha256=G7rlh_8PtTQMZpL3Ja0_qTT2gN6D_rG8AiAFmFBqzMM,1173
1
+ algokit_utils/__init__.py,sha256=he0sKUGvOgN2ROlXJ_6GOBqElfoDy3c5_XgVA3BYACU,1039
2
2
  algokit_utils/_debugging.py,sha256=nAiC10WXiZsvc0RPWOrMLpjJQZT_ItgcMl7D9Z4DfYc,11703
3
3
  algokit_utils/_legacy_v2/__init__.py,sha256=WcRE30axWjGnBB09bJCeTw9NT-2_jDN_CVJITFcIDc8,4689
4
4
  algokit_utils/_legacy_v2/_ensure_funded.py,sha256=k52b56CfWttPiu2gy09HIEiXl0eIz5WKQy-iuhxpSQg,6909
@@ -21,7 +21,7 @@ algokit_utils/application_client.py,sha256=5UIxXIBjukjRyjZPCeXmaNlAftbb3TziV7EfB
21
21
  algokit_utils/application_specification.py,sha256=wV0H088IudMqlxsW-gsZIfJyKA4e-zVwxJ-cR__ouBA,1379
22
22
  algokit_utils/applications/__init__.py,sha256=NGjhpBeExsQZOAYCT2QUFag1xuKoFiX-Ux5SR2GNzd8,452
23
23
  algokit_utils/applications/abi.py,sha256=OjTdn4szJPPeC8XmosdDYtkIIVgQSWAnqz2DHw5OH9g,10117
24
- algokit_utils/applications/app_client.py,sha256=WKedIu3CDamBW8dAAR5IBYCXkesvETkof1dwIqKHaNE,88474
24
+ algokit_utils/applications/app_client.py,sha256=wScCqe3j33EJbBGncRnAeGy55sHEgujtnL6WNmDVDRw,88477
25
25
  algokit_utils/applications/app_deployer.py,sha256=xJCu7SU66OTg5misSbSF0QI8abRB-DWAwAVKd1kNcPI,30685
26
26
  algokit_utils/applications/app_factory.py,sha256=jVAzoK1J9S-BTGHA5BLxT-cl0pWhPdf222W4fYpFihE,45352
27
27
  algokit_utils/applications/app_manager.py,sha256=8bboIswlwBQhPIqilSBMaxd83yHjIpkloezmtgcAdZY,22301
@@ -38,15 +38,14 @@ algokit_utils/beta/algorand_client.py,sha256=xDFvsMSha0Ki42BGvKvfScQWT_W9y4GeP_R
38
38
  algokit_utils/beta/client_manager.py,sha256=xDFvsMSha0Ki42BGvKvfScQWT_W9y4GeP_RWXjc3vnE,213
39
39
  algokit_utils/beta/composer.py,sha256=xDFvsMSha0Ki42BGvKvfScQWT_W9y4GeP_RWXjc3vnE,213
40
40
  algokit_utils/clients/__init__.py,sha256=qUuKBvfLnw4z6ZU9x7mc-mLjfnnXC9UcvtoeU33ZLJ8,136
41
- algokit_utils/clients/_algokit_core_bridge.py,sha256=qFgkcuYlf2Lw-2uZFA-TORPWU5CY02t6tS8mOvh9lfc,1882
42
- algokit_utils/clients/client_manager.py,sha256=p0pGx3rMrCR698L8cZVR0yNq21Y7j856vIjtiFlwV7s,28927
41
+ algokit_utils/clients/client_manager.py,sha256=eTkgaDVRl-auRnd_t3tQQzdrpLky6I1rQLR_1ZUXmrw,28615
43
42
  algokit_utils/clients/dispenser_api_client.py,sha256=3TgbnQsDmC9zSfDIykwNKDadbXLhQKZxUSbPwTDJISY,7336
44
43
  algokit_utils/common.py,sha256=5wl83vWw91RYdEC4hTTufqaptKiFtgjKLIyONDmRSH0,300
45
44
  algokit_utils/config.py,sha256=CvDH5B8uPWnm6wCHHlMsl-0lONzq26vPLvwmnbw7c-k,6048
46
45
  algokit_utils/deploy.py,sha256=UUtSDI6JcBUuto62FuirhUlDcjZwQyLkiERgDMx8P7A,330
47
46
  algokit_utils/dispenser_api.py,sha256=-EO4Dq3q_v4kSMey43kXJfoX8uCBPJpjEMTlLI7xn_I,324
48
47
  algokit_utils/errors/__init__.py,sha256=CmuiLVjzMAOYxPaIIwmYCNArsso_RtS2ssFoNdp5CMs,61
49
- algokit_utils/errors/logic_error.py,sha256=iDCyPTSK_aP8Pzjk-7PDcWqC1R764IJks6tle-d7znc,4116
48
+ algokit_utils/errors/logic_error.py,sha256=uxqUOU9-D1R5TrKturCbmmWRVlB024Ca4CfVi8x_sgo,4104
50
49
  algokit_utils/logic_error.py,sha256=3duw-l6tBr-DeapO0e0tYHoa9rOxP-QZZ6QWmN8L9tc,305
51
50
  algokit_utils/models/__init__.py,sha256=0aB_c5pnkqKl1Z0hkxM9qbKn2qVdizZE2DvziN9ObqM,465
52
51
  algokit_utils/models/account.py,sha256=eqGJvExzd7gDm3--DBDaIq6pJarxMPHZ-UySxZ9Qznk,6778
@@ -62,11 +61,10 @@ algokit_utils/protocols/account.py,sha256=CowaVY7ErBP84TWBHNvBjkZy18whPb8HIlMZtJ
62
61
  algokit_utils/protocols/typed_clients.py,sha256=UrQrHbN2SvS8pEFJ8JQodvouoWeBrQOQGZGyBQx1KLM,3322
63
62
  algokit_utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
63
  algokit_utils/transactions/__init__.py,sha256=7fYF3m6DyOGzbV36MT5svo0wSkj9AIz496kWgIWSAlk,225
65
- algokit_utils/transactions/_algokit_core_bridge.py,sha256=Q9Mf86fo-mOVu-8i1MeA91AkwhBnEjsx-4w3uVoY5dg,2191
66
- algokit_utils/transactions/transaction_composer.py,sha256=yHpL9FqYEFevh3WRIwHcBZ2ukEXPFmkzYK8nJev83i4,104959
64
+ algokit_utils/transactions/transaction_composer.py,sha256=eK-6l2W1CkbKID1ezi-zCs_TxA2i5ZTm3YTl8sT2Zfw,103995
67
65
  algokit_utils/transactions/transaction_creator.py,sha256=cuP6Xm-fhGoCc2FNSbLiEg3iQRwW38rfdTzsqPyEcpM,29053
68
66
  algokit_utils/transactions/transaction_sender.py,sha256=Wi3ws9S-Df1JeTlaSTXmq-WS24Gsq7WGsKk1B0z23ao,50117
69
- algokit_utils-4.1.0b4.dist-info/LICENSE,sha256=J5i7U1Q9Q2c7saUzlvFRmrCCFhQyXb5Juz_LO5omNUw,1076
70
- algokit_utils-4.1.0b4.dist-info/METADATA,sha256=WA_h3REWZghI1qzldGwvKkBp-B5__0pyMvKCRYCtKLg,2421
71
- algokit_utils-4.1.0b4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
72
- algokit_utils-4.1.0b4.dist-info/RECORD,,
67
+ algokit_utils-4.1.0b6.dist-info/LICENSE,sha256=J5i7U1Q9Q2c7saUzlvFRmrCCFhQyXb5Juz_LO5omNUw,1076
68
+ algokit_utils-4.1.0b6.dist-info/METADATA,sha256=hwblL6yxDLU3ysy51XqsbSkesYTdf2XG9FDoQObAN24,2421
69
+ algokit_utils-4.1.0b6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
70
+ algokit_utils-4.1.0b6.dist-info/RECORD,,
@@ -1,52 +0,0 @@
1
- import base64
2
- from collections.abc import Iterable
3
-
4
- from algosdk.encoding import msgpack_encode
5
- from algosdk.transaction import GenericSignedTransaction
6
- from algosdk.v2client.algod import AlgodClient
7
-
8
- from algokit_utils import _EXPERIMENTAL_DEPENDENCIES_INSTALLED
9
-
10
- if not _EXPERIMENTAL_DEPENDENCIES_INSTALLED:
11
- raise ImportError(
12
- "Installing experimental dependencies is necessary to use AlgodClientWithCore. "
13
- "Install this package with --group=experimental"
14
- )
15
-
16
- import algokit_algod_api
17
-
18
-
19
- class AlgodClientWithCore:
20
- """
21
- A decorator for AlgodClient that extends its functionality with algokit_algod_api capabilities.
22
- This class wraps an AlgodClient instance while maintaining the same interface.
23
- """
24
-
25
- def __init__(self, algod_client: AlgodClient):
26
- self._algod_client = algod_client
27
-
28
- configuration = algokit_algod_api.Configuration(
29
- host=algod_client.algod_address, api_key={"api_key": self._algod_client.algod_token}
30
- )
31
- api_client = algokit_algod_api.ApiClient(configuration)
32
- self._algod_core_client = algokit_algod_api.AlgodApi(api_client=api_client)
33
-
34
- def send_raw_transaction(self, txn):
35
- """
36
- Override the method to send a raw transaction using algokit_algod_api.
37
- """
38
- return self._algod_core_client.raw_transaction(base64.b64decode(txn))
39
-
40
- def send_transactions(self, txns: Iterable[GenericSignedTransaction]):
41
- """
42
- Override the method to send multiple transactions using algokit_algod_api.
43
- """
44
- return self.send_raw_transaction(
45
- base64.b64encode(b"".join(base64.b64decode(msgpack_encode(txn)) for txn in txns))
46
- )
47
-
48
- def __getattr__(self, name):
49
- """
50
- Delegate all other method calls to the wrapped AlgodClient instance.
51
- """
52
- return getattr(self._algod_client, name)
@@ -1,76 +0,0 @@
1
- import base64
2
- from typing import cast
3
-
4
- import algosdk.transaction
5
- from algokit_transact import (
6
- FeeParams,
7
- PaymentTransactionFields,
8
- Transaction,
9
- TransactionType,
10
- address_from_string,
11
- assign_fee,
12
- encode_transaction_raw,
13
- )
14
-
15
-
16
- def build_payment_with_core( # noqa: PLR0913
17
- sender,
18
- sp,
19
- receiver,
20
- amt,
21
- close_remainder_to=None,
22
- note=None,
23
- lease=None,
24
- rekey_to=None,
25
- static_fee=None,
26
- max_fee=None,
27
- extra_fee=None,
28
- ) -> algosdk.transaction.PaymentTxn:
29
- # Determine static fee based on parameters or suggested params
30
- static_fee_value = None
31
- if static_fee is not None:
32
- static_fee_value = static_fee
33
- elif sp.flat_fee:
34
- static_fee_value = sp.fee
35
-
36
- txn = Transaction(
37
- transaction_type=TransactionType.PAYMENT,
38
- sender=address_from_string(sender),
39
- fee=static_fee_value,
40
- first_valid=sp.first,
41
- last_valid=sp.last,
42
- genesis_hash=base64.b64decode(sp.gh),
43
- genesis_id=sp.gen,
44
- note=note,
45
- lease=lease,
46
- rekey_to=address_from_string(rekey_to) if rekey_to else None,
47
- payment=PaymentTransactionFields(
48
- receiver=address_from_string(receiver),
49
- amount=amt,
50
- close_remainder_to=address_from_string(close_remainder_to) if close_remainder_to else None,
51
- ),
52
- )
53
-
54
- if txn.fee is not None:
55
- # Static fee is already set, encode and return directly
56
- return cast(
57
- algosdk.transaction.PaymentTxn,
58
- algosdk.encoding.msgpack_decode(base64.b64encode(encode_transaction_raw(txn)).decode("utf-8")),
59
- )
60
- else:
61
- # Use assign_fee with fee parameters
62
- min_fee = sp.min_fee or algosdk.constants.MIN_TXN_FEE
63
- txn_with_fee = assign_fee(
64
- txn,
65
- FeeParams(
66
- fee_per_byte=sp.fee,
67
- min_fee=min_fee,
68
- max_fee=max_fee,
69
- extra_fee=extra_fee,
70
- ),
71
- )
72
-
73
- return cast(
74
- algosdk.transaction.PaymentTxn,
75
- algosdk.encoding.msgpack_decode(base64.b64encode(encode_transaction_raw(txn_with_fee)).decode("utf-8")),
76
- )