algokit-utils 4.0.2b1__py3-none-any.whl → 4.1.0__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.

@@ -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
 
@@ -449,21 +452,16 @@ class _StateAccessor:
449
452
  if not box.name_raw.startswith(prefix):
450
453
  continue
451
454
 
452
- encoded_key = prefix + box.name_raw
453
- base64_key = base64.b64encode(encoded_key).decode("utf-8")
454
-
455
455
  try:
456
456
  key = get_abi_decoded_value(box.name_raw[len(prefix) :], metadata.key_type, self._app_spec.structs)
457
457
  value = get_abi_decoded_value(
458
- self._algorand.app.get_box_value(self._app_id, base64.b64decode(base64_key)),
458
+ self._algorand.app.get_box_value(self._app_id, box.name_raw),
459
459
  metadata.value_type,
460
460
  self._app_spec.structs,
461
461
  )
462
462
  result[str(key)] = value
463
463
  except Exception as e:
464
- if "Failed to decode key" in str(e):
465
- raise ValueError(f"Failed to decode key {base64_key}") from e
466
- raise ValueError(f"Failed to decode value for key {base64_key}") from e
464
+ raise ValueError(f"Failed to decode value for key {box.name_raw.decode('utf-8')}") from e
467
465
 
468
466
  return result
469
467
 
@@ -1183,7 +1181,6 @@ class _TransactionSender:
1183
1181
  :param params: Parameters for the application call including method and transaction options
1184
1182
  :param send_params: Send parameters
1185
1183
  :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
1184
  """
1188
1185
  is_read_only_call = (
1189
1186
  params.on_complete == algosdk.transaction.OnComplete.NoOpOC or params.on_complete is None
@@ -1194,14 +1191,10 @@ class _TransactionSender:
1194
1191
  readonly_send_params = send_params or SendParams()
1195
1192
 
1196
1193
  # 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
- )
1194
+ # With maximum opcode budget provided, ensure_budget won't create inner transactions,
1195
+ # so fee coverage is no longer a concern for read-only calls.
1196
+ # If max_fee is provided, use it as static_fee for potential benefits.
1197
+ if readonly_send_params.get("cover_app_call_inner_transaction_fees") and params.max_fee is not None:
1205
1198
  readonly_params = replace(readonly_params, static_fee=params.max_fee, extra_fee=None)
1206
1199
 
1207
1200
  method_call_to_simulate = self._algorand.new_group().add_app_call_method_call(
@@ -1215,11 +1208,13 @@ class _TransactionSender:
1215
1208
  skip_signatures=True,
1216
1209
  allow_more_logs=True,
1217
1210
  allow_empty_signatures=True,
1218
- extra_opcode_budget=None,
1211
+ extra_opcode_budget=MAX_SIMULATE_OPCODE_BUDGET,
1219
1212
  exec_trace_config=None,
1220
1213
  simulation_round=None,
1221
1214
  )
1222
1215
  except Exception as e:
1216
+ # For read-only calls with max opcode budget, fee issues should be rare
1217
+ # but we can still provide helpful error message if they occur
1223
1218
  if readonly_send_params.get("cover_app_call_inner_transaction_fees") and "fee too small" in str(e):
1224
1219
  raise ValueError(
1225
1220
  "Fees were too small. You may need to increase the transaction `maxFee`."
@@ -447,7 +447,8 @@ class AppDeployer:
447
447
  composer = self._transaction_sender.new_group()
448
448
 
449
449
  # Add create transaction
450
- if isinstance(deployment.create_params, AppCreateMethodCallParams):
450
+ has_abi_create = isinstance(deployment.create_params, AppCreateMethodCallParams)
451
+ if has_abi_create:
451
452
  composer.add_app_create_method_call(
452
453
  AppCreateMethodCallParams(
453
454
  **{
@@ -467,10 +468,10 @@ class AppDeployer:
467
468
  }
468
469
  )
469
470
  )
470
- create_txn_index = composer.count() - 1
471
471
 
472
472
  # Add delete transaction
473
- if isinstance(deployment.delete_params, AppDeleteMethodCallParams):
473
+ has_abi_delete = isinstance(deployment.delete_params, AppDeleteMethodCallParams)
474
+ if has_abi_delete:
474
475
  delete_call_params = AppDeleteMethodCallParams(
475
476
  **{
476
477
  **deployment.delete_params.__dict__,
@@ -486,12 +487,15 @@ class AppDeployer:
486
487
  }
487
488
  )
488
489
  composer.add_app_delete(delete_params)
489
- delete_txn_index = composer.count() - 1
490
490
 
491
- result = composer.send()
491
+ result = composer.send(deployment.send_params)
492
492
 
493
- create_result = SendAppCreateTransactionResult[ABIReturn].from_composer_result(result, create_txn_index)
494
- delete_result = SendAppTransactionResult[ABIReturn].from_composer_result(result, delete_txn_index)
493
+ create_result = SendAppCreateTransactionResult[ABIReturn].from_composer_result(
494
+ result, is_abi=has_abi_create, index=0
495
+ )
496
+ delete_result = SendAppTransactionResult[ABIReturn].from_composer_result(
497
+ result, is_abi=has_abi_delete, index=-1
498
+ )
495
499
 
496
500
  app_id = int(result.confirmations[0]["application-index"]) # type: ignore[call-overload]
497
501
  app_metadata = ApplicationMetaData(
@@ -81,7 +81,9 @@ class SendSingleTransactionResult:
81
81
  """The ABI return value if applicable"""
82
82
 
83
83
  @classmethod
84
- def from_composer_result(cls, result: SendAtomicTransactionComposerResults, index: int = -1) -> Self:
84
+ def from_composer_result(
85
+ cls, result: SendAtomicTransactionComposerResults, *, is_abi: bool = False, index: int = -1
86
+ ) -> Self:
85
87
  # Get base parameters
86
88
  base_params = {
87
89
  "transaction": result.transactions[index],
@@ -104,12 +106,12 @@ class SendSingleTransactionResult:
104
106
  {
105
107
  "app_id": app_id,
106
108
  "app_address": algosdk.logic.get_application_address(app_id),
107
- "abi_return": result.returns[index] if result.returns else None, # type: ignore[dict-item]
109
+ "abi_return": result.returns[index] if result.returns and is_abi else None, # type: ignore[dict-item]
108
110
  }
109
111
  )
110
112
  # For regular app transactions, just add abi_return
111
113
  elif cls is SendAppTransactionResult:
112
- base_params["abi_return"] = result.returns[index] if result.returns else None # type: ignore[assignment]
114
+ base_params["abi_return"] = result.returns[index] if result.returns and is_abi else None # type: ignore[assignment]
113
115
 
114
116
  return cls(**base_params) # type: ignore[arg-type]
115
117
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: algokit-utils
3
- Version: 4.0.2b1
3
+ Version: 4.1.0
4
4
  Summary: Utilities for Algorand development for use by AlgoKit
5
5
  License: MIT
6
6
  Author: Algorand Foundation
@@ -21,8 +21,8 @@ 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
25
- algokit_utils/applications/app_deployer.py,sha256=-6pCs61PdFMMrnDIpXOuaIlr6TgDkvsB6vwbOZhOiZ0,30606
24
+ algokit_utils/applications/app_client.py,sha256=891BMnUOIOenEWgeelSIMgi0Wj4kggluWiKAu6-GYrE,88208
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
28
28
  algokit_utils/applications/app_spec/__init__.py,sha256=HtjAhAqHNFml9WbRKGmhJnwyJeW8AztPRO_BriQ84vs,140
@@ -63,8 +63,8 @@ algokit_utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  algokit_utils/transactions/__init__.py,sha256=7fYF3m6DyOGzbV36MT5svo0wSkj9AIz496kWgIWSAlk,225
64
64
  algokit_utils/transactions/transaction_composer.py,sha256=eK-6l2W1CkbKID1ezi-zCs_TxA2i5ZTm3YTl8sT2Zfw,103995
65
65
  algokit_utils/transactions/transaction_creator.py,sha256=cuP6Xm-fhGoCc2FNSbLiEg3iQRwW38rfdTzsqPyEcpM,29053
66
- algokit_utils/transactions/transaction_sender.py,sha256=4u2FON3YM4_DKPde6gSkZFAH1wp7FC8E65HpQ803RNo,50056
67
- algokit_utils-4.0.2b1.dist-info/LICENSE,sha256=J5i7U1Q9Q2c7saUzlvFRmrCCFhQyXb5Juz_LO5omNUw,1076
68
- algokit_utils-4.0.2b1.dist-info/METADATA,sha256=_voF9wDpeJ2vIPFXZixsmX6V8F2bFDthSwR4NLOKQ-o,2421
69
- algokit_utils-4.0.2b1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
70
- algokit_utils-4.0.2b1.dist-info/RECORD,,
66
+ algokit_utils/transactions/transaction_sender.py,sha256=Wi3ws9S-Df1JeTlaSTXmq-WS24Gsq7WGsKk1B0z23ao,50117
67
+ algokit_utils-4.1.0.dist-info/LICENSE,sha256=J5i7U1Q9Q2c7saUzlvFRmrCCFhQyXb5Juz_LO5omNUw,1076
68
+ algokit_utils-4.1.0.dist-info/METADATA,sha256=9Et8L9-7fqp3dk3J_N8X6_6AWHm4EZf7qy7IIyuYEA4,2419
69
+ algokit_utils-4.1.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
70
+ algokit_utils-4.1.0.dist-info/RECORD,,