algokit-utils 3.0.0b1__py3-none-any.whl → 3.0.0b3__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.

Files changed (70) hide show
  1. algokit_utils/__init__.py +23 -183
  2. algokit_utils/_debugging.py +123 -97
  3. algokit_utils/_legacy_v2/__init__.py +177 -0
  4. algokit_utils/{_ensure_funded.py → _legacy_v2/_ensure_funded.py} +19 -18
  5. algokit_utils/{_transfer.py → _legacy_v2/_transfer.py} +24 -23
  6. algokit_utils/_legacy_v2/account.py +203 -0
  7. algokit_utils/_legacy_v2/application_client.py +1471 -0
  8. algokit_utils/_legacy_v2/application_specification.py +21 -0
  9. algokit_utils/_legacy_v2/asset.py +168 -0
  10. algokit_utils/_legacy_v2/common.py +28 -0
  11. algokit_utils/_legacy_v2/deploy.py +822 -0
  12. algokit_utils/_legacy_v2/logic_error.py +14 -0
  13. algokit_utils/{models.py → _legacy_v2/models.py} +19 -142
  14. algokit_utils/_legacy_v2/network_clients.py +140 -0
  15. algokit_utils/account.py +12 -183
  16. algokit_utils/accounts/__init__.py +2 -0
  17. algokit_utils/accounts/account_manager.py +909 -0
  18. algokit_utils/accounts/kmd_account_manager.py +159 -0
  19. algokit_utils/algorand.py +265 -0
  20. algokit_utils/application_client.py +9 -1453
  21. algokit_utils/application_specification.py +39 -197
  22. algokit_utils/applications/__init__.py +7 -0
  23. algokit_utils/applications/abi.py +276 -0
  24. algokit_utils/applications/app_client.py +2054 -0
  25. algokit_utils/applications/app_deployer.py +600 -0
  26. algokit_utils/applications/app_factory.py +826 -0
  27. algokit_utils/applications/app_manager.py +470 -0
  28. algokit_utils/applications/app_spec/__init__.py +2 -0
  29. algokit_utils/applications/app_spec/arc32.py +207 -0
  30. algokit_utils/applications/app_spec/arc56.py +1023 -0
  31. algokit_utils/applications/enums.py +40 -0
  32. algokit_utils/asset.py +32 -168
  33. algokit_utils/assets/__init__.py +1 -0
  34. algokit_utils/assets/asset_manager.py +320 -0
  35. algokit_utils/beta/_utils.py +36 -0
  36. algokit_utils/beta/account_manager.py +4 -195
  37. algokit_utils/beta/algorand_client.py +4 -314
  38. algokit_utils/beta/client_manager.py +5 -74
  39. algokit_utils/beta/composer.py +5 -712
  40. algokit_utils/clients/__init__.py +2 -0
  41. algokit_utils/clients/client_manager.py +656 -0
  42. algokit_utils/clients/dispenser_api_client.py +192 -0
  43. algokit_utils/common.py +8 -26
  44. algokit_utils/config.py +71 -18
  45. algokit_utils/deploy.py +7 -892
  46. algokit_utils/dispenser_api.py +8 -176
  47. algokit_utils/errors/__init__.py +1 -0
  48. algokit_utils/errors/logic_error.py +121 -0
  49. algokit_utils/logic_error.py +7 -80
  50. algokit_utils/models/__init__.py +8 -0
  51. algokit_utils/models/account.py +197 -0
  52. algokit_utils/models/amount.py +198 -0
  53. algokit_utils/models/application.py +61 -0
  54. algokit_utils/models/network.py +25 -0
  55. algokit_utils/models/simulate.py +11 -0
  56. algokit_utils/models/state.py +59 -0
  57. algokit_utils/models/transaction.py +100 -0
  58. algokit_utils/network_clients.py +7 -152
  59. algokit_utils/protocols/__init__.py +2 -0
  60. algokit_utils/protocols/account.py +22 -0
  61. algokit_utils/protocols/typed_clients.py +108 -0
  62. algokit_utils/transactions/__init__.py +3 -0
  63. algokit_utils/transactions/transaction_composer.py +2287 -0
  64. algokit_utils/transactions/transaction_creator.py +156 -0
  65. algokit_utils/transactions/transaction_sender.py +574 -0
  66. {algokit_utils-3.0.0b1.dist-info → algokit_utils-3.0.0b3.dist-info}/METADATA +13 -8
  67. algokit_utils-3.0.0b3.dist-info/RECORD +70 -0
  68. {algokit_utils-3.0.0b1.dist-info → algokit_utils-3.0.0b3.dist-info}/WHEEL +1 -1
  69. algokit_utils-3.0.0b1.dist-info/RECORD +0 -24
  70. {algokit_utils-3.0.0b1.dist-info → algokit_utils-3.0.0b3.dist-info}/LICENSE +0 -0
@@ -0,0 +1,574 @@
1
+ from collections.abc import Callable
2
+ from dataclasses import dataclass
3
+ from typing import Any, Generic, TypeVar
4
+
5
+ import algosdk
6
+ import algosdk.atomic_transaction_composer
7
+ from algosdk.transaction import Transaction
8
+ from typing_extensions import Self
9
+
10
+ from algokit_utils.applications.abi import ABIReturn
11
+ from algokit_utils.applications.app_manager import AppManager
12
+ from algokit_utils.assets.asset_manager import AssetManager
13
+ from algokit_utils.config import config
14
+ from algokit_utils.models.transaction import SendParams, TransactionWrapper
15
+ from algokit_utils.transactions.transaction_composer import (
16
+ AppCallMethodCallParams,
17
+ AppCallParams,
18
+ AppCreateMethodCallParams,
19
+ AppCreateParams,
20
+ AppDeleteMethodCallParams,
21
+ AppDeleteParams,
22
+ AppUpdateMethodCallParams,
23
+ AppUpdateParams,
24
+ AssetConfigParams,
25
+ AssetCreateParams,
26
+ AssetDestroyParams,
27
+ AssetFreezeParams,
28
+ AssetOptInParams,
29
+ AssetOptOutParams,
30
+ AssetTransferParams,
31
+ OfflineKeyRegistrationParams,
32
+ OnlineKeyRegistrationParams,
33
+ PaymentParams,
34
+ SendAtomicTransactionComposerResults,
35
+ TransactionComposer,
36
+ TxnParams,
37
+ )
38
+
39
+ __all__ = [
40
+ "AlgorandClientTransactionSender",
41
+ "SendAppCreateTransactionResult",
42
+ "SendAppTransactionResult",
43
+ "SendAppUpdateTransactionResult",
44
+ "SendSingleAssetCreateTransactionResult",
45
+ "SendSingleTransactionResult",
46
+ ]
47
+
48
+ logger = config.logger
49
+
50
+
51
+ TxnParamsT = TypeVar("TxnParamsT", bound=TxnParams)
52
+
53
+
54
+ @dataclass(frozen=True, kw_only=True)
55
+ class SendSingleTransactionResult:
56
+ """Base class for transaction results.
57
+
58
+ Represents the result of sending a single transaction.
59
+ """
60
+
61
+ transaction: TransactionWrapper # Last transaction
62
+ confirmation: algosdk.v2client.algod.AlgodResponseType # Last confirmation
63
+
64
+ # Fields from SendAtomicTransactionComposerResults
65
+ group_id: str
66
+ tx_id: str | None = None
67
+ tx_ids: list[str] # Full array of transaction IDs
68
+ transactions: list[TransactionWrapper]
69
+ confirmations: list[algosdk.v2client.algod.AlgodResponseType]
70
+ returns: list[ABIReturn] | None = None
71
+
72
+ @classmethod
73
+ def from_composer_result(cls, result: SendAtomicTransactionComposerResults, index: int = -1) -> Self:
74
+ # Get base parameters
75
+ base_params = {
76
+ "transaction": result.transactions[index],
77
+ "confirmation": result.confirmations[index],
78
+ "group_id": result.group_id,
79
+ "tx_id": result.tx_ids[index],
80
+ "tx_ids": result.tx_ids,
81
+ "transactions": [result.transactions[index]],
82
+ "confirmations": result.confirmations,
83
+ "returns": result.returns,
84
+ }
85
+
86
+ # For asset creation, extract asset_id from confirmation
87
+ if cls is SendSingleAssetCreateTransactionResult:
88
+ base_params["asset_id"] = result.confirmations[index]["asset-index"] # type: ignore[call-overload]
89
+ # For app creation, extract app_id and calculate app_address
90
+ elif cls is SendAppCreateTransactionResult:
91
+ app_id = result.confirmations[index]["application-index"] # type: ignore[call-overload]
92
+ base_params.update(
93
+ {
94
+ "app_id": app_id,
95
+ "app_address": algosdk.logic.get_application_address(app_id),
96
+ "abi_return": result.returns[index] if result.returns else None, # type: ignore[dict-item]
97
+ }
98
+ )
99
+ # For regular app transactions, just add abi_return
100
+ elif cls is SendAppTransactionResult:
101
+ base_params["abi_return"] = result.returns[index] if result.returns else None # type: ignore[assignment]
102
+
103
+ return cls(**base_params) # type: ignore[arg-type]
104
+
105
+
106
+ @dataclass(frozen=True, kw_only=True)
107
+ class SendSingleAssetCreateTransactionResult(SendSingleTransactionResult):
108
+ """Result of creating a new ASA (Algorand Standard Asset).
109
+
110
+ Contains the asset ID of the newly created asset.
111
+ """
112
+
113
+ asset_id: int
114
+
115
+
116
+ ABIReturnT = TypeVar("ABIReturnT")
117
+
118
+
119
+ @dataclass(frozen=True)
120
+ class SendAppTransactionResult(SendSingleTransactionResult, Generic[ABIReturnT]):
121
+ """Result of an application transaction.
122
+
123
+ Contains the ABI return value if applicable.
124
+ """
125
+
126
+ abi_return: ABIReturnT | None = None
127
+
128
+
129
+ @dataclass(frozen=True)
130
+ class SendAppUpdateTransactionResult(SendAppTransactionResult[ABIReturnT]):
131
+ """Result of updating an application.
132
+
133
+ Contains the compiled approval and clear programs.
134
+ """
135
+
136
+ compiled_approval: Any | None = None
137
+ compiled_clear: Any | None = None
138
+
139
+
140
+ @dataclass(frozen=True, kw_only=True)
141
+ class SendAppCreateTransactionResult(SendAppUpdateTransactionResult[ABIReturnT]):
142
+ """Result of creating a new application.
143
+
144
+ Contains the app ID and address of the newly created application.
145
+ """
146
+
147
+ app_id: int
148
+ app_address: str
149
+
150
+
151
+ class AlgorandClientTransactionSender:
152
+ """Orchestrates sending transactions for AlgorandClient.
153
+
154
+ Provides methods to send various types of transactions including payments,
155
+ asset operations, and application calls.
156
+ """
157
+
158
+ def __init__(
159
+ self,
160
+ new_group: Callable[[], TransactionComposer],
161
+ asset_manager: AssetManager,
162
+ app_manager: AppManager,
163
+ algod_client: algosdk.v2client.algod.AlgodClient,
164
+ ) -> None:
165
+ self._new_group = new_group
166
+ self._asset_manager = asset_manager
167
+ self._app_manager = app_manager
168
+ self._algod = algod_client
169
+
170
+ def new_group(self) -> TransactionComposer:
171
+ """Create a new transaction group.
172
+
173
+ :return: A new TransactionComposer instance
174
+ """
175
+ return self._new_group()
176
+
177
+ def _send(
178
+ self,
179
+ c: Callable[[TransactionComposer], Callable[[TxnParamsT], TransactionComposer]],
180
+ pre_log: Callable[[TxnParamsT, Transaction], str] | None = None,
181
+ post_log: Callable[[TxnParamsT, SendSingleTransactionResult], str] | None = None,
182
+ ) -> Callable[[TxnParamsT, SendParams | None], SendSingleTransactionResult]:
183
+ def send_transaction(params: TxnParamsT, send_params: SendParams | None = None) -> SendSingleTransactionResult:
184
+ composer = self.new_group()
185
+ c(composer)(params)
186
+
187
+ if pre_log:
188
+ transaction = composer.build().transactions[-1].txn
189
+ logger.debug(pre_log(params, transaction))
190
+
191
+ raw_result = composer.send(
192
+ send_params,
193
+ )
194
+ raw_result_dict = raw_result.__dict__.copy()
195
+ raw_result_dict["transactions"] = raw_result.transactions
196
+ del raw_result_dict["simulate_response"]
197
+
198
+ result = SendSingleTransactionResult(
199
+ **raw_result_dict,
200
+ confirmation=raw_result.confirmations[-1],
201
+ transaction=raw_result_dict["transactions"][-1],
202
+ tx_id=raw_result.tx_ids[-1],
203
+ )
204
+
205
+ if post_log:
206
+ logger.debug(post_log(params, result))
207
+
208
+ return result
209
+
210
+ return send_transaction
211
+
212
+ def _send_app_call(
213
+ self,
214
+ c: Callable[[TransactionComposer], Callable[[TxnParamsT], TransactionComposer]],
215
+ pre_log: Callable[[TxnParamsT, Transaction], str] | None = None,
216
+ post_log: Callable[[TxnParamsT, SendSingleTransactionResult], str] | None = None,
217
+ ) -> Callable[[TxnParamsT, SendParams | None], SendAppTransactionResult[ABIReturn]]:
218
+ def send_app_call(
219
+ params: TxnParamsT, send_params: SendParams | None = None
220
+ ) -> SendAppTransactionResult[ABIReturn]:
221
+ result = self._send(c, pre_log, post_log)(params, send_params)
222
+ return SendAppTransactionResult[ABIReturn](
223
+ **result.__dict__,
224
+ abi_return=AppManager.get_abi_return(result.confirmation, getattr(params, "method", None)),
225
+ )
226
+
227
+ return send_app_call
228
+
229
+ def _send_app_update_call(
230
+ self,
231
+ c: Callable[[TransactionComposer], Callable[[TxnParamsT], TransactionComposer]],
232
+ pre_log: Callable[[TxnParamsT, Transaction], str] | None = None,
233
+ post_log: Callable[[TxnParamsT, SendSingleTransactionResult], str] | None = None,
234
+ ) -> Callable[[TxnParamsT, SendParams | None], SendAppUpdateTransactionResult[ABIReturn]]:
235
+ def send_app_update_call(
236
+ params: TxnParamsT, send_params: SendParams | None = None
237
+ ) -> SendAppUpdateTransactionResult[ABIReturn]:
238
+ result = self._send_app_call(c, pre_log, post_log)(params, send_params)
239
+
240
+ if not isinstance(
241
+ params, AppCreateParams | AppUpdateParams | AppCreateMethodCallParams | AppUpdateMethodCallParams
242
+ ):
243
+ raise TypeError("Invalid parameter type")
244
+
245
+ compiled_approval = (
246
+ self._app_manager.get_compilation_result(params.approval_program)
247
+ if isinstance(params.approval_program, str)
248
+ else params.approval_program
249
+ )
250
+ compiled_clear = (
251
+ self._app_manager.get_compilation_result(params.clear_state_program)
252
+ if isinstance(params.clear_state_program, str)
253
+ else params.clear_state_program
254
+ )
255
+
256
+ return SendAppUpdateTransactionResult[ABIReturn](
257
+ **result.__dict__,
258
+ compiled_approval=compiled_approval,
259
+ compiled_clear=compiled_clear,
260
+ )
261
+
262
+ return send_app_update_call
263
+
264
+ def _send_app_create_call(
265
+ self,
266
+ c: Callable[[TransactionComposer], Callable[[TxnParamsT], TransactionComposer]],
267
+ pre_log: Callable[[TxnParamsT, Transaction], str] | None = None,
268
+ post_log: Callable[[TxnParamsT, SendSingleTransactionResult], str] | None = None,
269
+ ) -> Callable[[TxnParamsT, SendParams | None], SendAppCreateTransactionResult[ABIReturn]]:
270
+ def send_app_create_call(
271
+ params: TxnParamsT, send_params: SendParams | None = None
272
+ ) -> SendAppCreateTransactionResult[ABIReturn]:
273
+ result = self._send_app_update_call(c, pre_log, post_log)(params, send_params)
274
+ app_id = int(result.confirmation["application-index"]) # type: ignore[call-overload]
275
+
276
+ return SendAppCreateTransactionResult[ABIReturn](
277
+ **result.__dict__,
278
+ app_id=app_id,
279
+ app_address=algosdk.logic.get_application_address(app_id),
280
+ )
281
+
282
+ return send_app_create_call
283
+
284
+ def _get_method_call_for_log(self, method: algosdk.abi.Method, args: list[Any]) -> str:
285
+ """Helper function to format method call logs similar to TypeScript version"""
286
+ args_str = str([str(a) if not isinstance(a, bytes | bytearray) else a.hex() for a in args])
287
+ return f"{method.name}({args_str})"
288
+
289
+ def payment(self, params: PaymentParams, send_params: SendParams | None = None) -> SendSingleTransactionResult:
290
+ """Send a payment transaction to transfer Algo between accounts.
291
+
292
+ :param params: Payment transaction parameters
293
+ :param send_params: Send parameters
294
+ :return: Result of the payment transaction
295
+ """
296
+ return self._send(
297
+ lambda c: c.add_payment,
298
+ pre_log=lambda params, transaction: (
299
+ f"Sending {params.amount} from {params.sender} to {params.receiver} "
300
+ f"via transaction {transaction.get_txid()}"
301
+ ),
302
+ )(params, send_params)
303
+
304
+ def asset_create(
305
+ self, params: AssetCreateParams, send_params: SendParams | None = None
306
+ ) -> SendSingleAssetCreateTransactionResult:
307
+ """Create a new Algorand Standard Asset.
308
+
309
+ :param params: Asset creation parameters
310
+ :param send_params: Send parameters
311
+ :return: Result containing the new asset ID
312
+ """
313
+ result = self._send(
314
+ lambda c: c.add_asset_create,
315
+ post_log=lambda params, result: (
316
+ f"Created asset{f' {params.asset_name}' if hasattr(params, 'asset_name') else ''}"
317
+ f"{f' ({params.unit_name})' if hasattr(params, 'unit_name') else ''} with "
318
+ f"{params.total} units and {getattr(params, 'decimals', 0)} decimals created by "
319
+ f"{params.sender} with ID {result.confirmation['asset-index']} via transaction " # type: ignore[call-overload]
320
+ f"{result.tx_ids[-1]}"
321
+ ),
322
+ )(params, send_params)
323
+
324
+ return SendSingleAssetCreateTransactionResult(
325
+ **result.__dict__,
326
+ asset_id=int(result.confirmation["asset-index"]), # type: ignore[call-overload]
327
+ )
328
+
329
+ def asset_config(
330
+ self, params: AssetConfigParams, send_params: SendParams | None = None
331
+ ) -> SendSingleTransactionResult:
332
+ """Configure an existing Algorand Standard Asset.
333
+
334
+ :param params: Asset configuration parameters
335
+ :param send_params: Send parameters
336
+ :return: Result of the configuration transaction
337
+ """
338
+ return self._send(
339
+ lambda c: c.add_asset_config,
340
+ pre_log=lambda params, transaction: (
341
+ f"Configuring asset with ID {params.asset_id} via transaction {transaction.get_txid()}"
342
+ ),
343
+ )(params, send_params)
344
+
345
+ def asset_freeze(
346
+ self, params: AssetFreezeParams, send_params: SendParams | None = None
347
+ ) -> SendSingleTransactionResult:
348
+ """Freeze or unfreeze an Algorand Standard Asset for an account.
349
+
350
+ :param params: Asset freeze parameters
351
+ :param send_params: Send parameters
352
+ :return: Result of the freeze transaction
353
+ """
354
+ return self._send(
355
+ lambda c: c.add_asset_freeze,
356
+ pre_log=lambda params, transaction: (
357
+ f"Freezing asset with ID {params.asset_id} via transaction {transaction.get_txid()}"
358
+ ),
359
+ )(params, send_params)
360
+
361
+ def asset_destroy(
362
+ self, params: AssetDestroyParams, send_params: SendParams | None = None
363
+ ) -> SendSingleTransactionResult:
364
+ """Destroys an Algorand Standard Asset.
365
+
366
+ :param params: Asset destruction parameters
367
+ :param send_params: Send parameters
368
+ :return: Result of the destroy transaction
369
+ """
370
+ return self._send(
371
+ lambda c: c.add_asset_destroy,
372
+ pre_log=lambda params, transaction: (
373
+ f"Destroying asset with ID {params.asset_id} via transaction {transaction.get_txid()}"
374
+ ),
375
+ )(params, send_params)
376
+
377
+ def asset_transfer(
378
+ self, params: AssetTransferParams, send_params: SendParams | None = None
379
+ ) -> SendSingleTransactionResult:
380
+ """Transfer an Algorand Standard Asset.
381
+
382
+ :param params: Asset transfer parameters
383
+ :param send_params: Send parameters
384
+ :return: Result of the transfer transaction
385
+ """
386
+ return self._send(
387
+ lambda c: c.add_asset_transfer,
388
+ pre_log=lambda params, transaction: (
389
+ f"Transferring {params.amount} units of asset with ID {params.asset_id} from "
390
+ f"{params.sender} to {params.receiver} via transaction {transaction.get_txid()}"
391
+ ),
392
+ )(params, send_params)
393
+
394
+ def asset_opt_in(
395
+ self, params: AssetOptInParams, send_params: SendParams | None = None
396
+ ) -> SendSingleTransactionResult:
397
+ """Opt an account into an Algorand Standard Asset.
398
+
399
+ :param params: Asset opt-in parameters
400
+ :param send_params: Send parameters
401
+ :return: Result of the opt-in transaction
402
+ """
403
+ return self._send(
404
+ lambda c: c.add_asset_opt_in,
405
+ pre_log=lambda params, transaction: (
406
+ f"Opting in {params.sender} to asset with ID {params.asset_id} via transaction "
407
+ f"{transaction.get_txid()}"
408
+ ),
409
+ )(params, send_params)
410
+
411
+ def asset_opt_out(
412
+ self,
413
+ *,
414
+ params: AssetOptOutParams,
415
+ send_params: SendParams | None = None,
416
+ ensure_zero_balance: bool = True,
417
+ ) -> SendSingleTransactionResult:
418
+ """Opt an account out of an Algorand Standard Asset.
419
+
420
+ :param params: Asset opt-out parameters
421
+ :param send_params: Send parameters
422
+ :param ensure_zero_balance: Check if account has zero balance before opt-out, defaults to True
423
+ :raises ValueError: If account has non-zero balance or is not opted in
424
+ :return: Result of the opt-out transaction
425
+ """
426
+ if ensure_zero_balance:
427
+ try:
428
+ account_asset_info = self._asset_manager.get_account_information(params.sender, params.asset_id)
429
+ balance = account_asset_info.balance
430
+ if balance != 0:
431
+ raise ValueError(
432
+ f"Account {params.sender} does not have a zero balance for Asset "
433
+ f"{params.asset_id}; can't opt-out."
434
+ )
435
+ except Exception as e:
436
+ raise ValueError(
437
+ f"Account {params.sender} is not opted-in to Asset {params.asset_id}; " "can't opt-out."
438
+ ) from e
439
+
440
+ if not hasattr(params, "creator"):
441
+ asset_info = self._asset_manager.get_by_id(params.asset_id)
442
+ params = AssetOptOutParams(
443
+ **params.__dict__,
444
+ creator=asset_info.creator,
445
+ )
446
+
447
+ creator = params.__dict__.get("creator")
448
+ return self._send(
449
+ lambda c: c.add_asset_opt_out,
450
+ pre_log=lambda params, transaction: (
451
+ f"Opting {params.sender} out of asset with ID {params.asset_id} to creator "
452
+ f"{creator} via transaction {transaction.get_txid()}"
453
+ ),
454
+ )(params, send_params)
455
+
456
+ def app_create(
457
+ self, params: AppCreateParams, send_params: SendParams | None = None
458
+ ) -> SendAppCreateTransactionResult[ABIReturn]:
459
+ """Create a new application.
460
+
461
+ :param params: Application creation parameters
462
+ :param send_params: Send parameters
463
+ :return: Result containing the new application ID and address
464
+ """
465
+ return self._send_app_create_call(lambda c: c.add_app_create)(params, send_params)
466
+
467
+ def app_update(
468
+ self, params: AppUpdateParams, send_params: SendParams | None = None
469
+ ) -> SendAppUpdateTransactionResult[ABIReturn]:
470
+ """Update an application.
471
+
472
+ :param params: Application update parameters
473
+ :param send_params: Send parameters
474
+ :return: Result containing the compiled programs
475
+ """
476
+ return self._send_app_update_call(lambda c: c.add_app_update)(params, send_params)
477
+
478
+ def app_delete(
479
+ self, params: AppDeleteParams, send_params: SendParams | None = None
480
+ ) -> SendAppTransactionResult[ABIReturn]:
481
+ """Delete an application.
482
+
483
+ :param params: Application deletion parameters
484
+ :param send_params: Send parameters
485
+ :return: Result of the deletion transaction
486
+ """
487
+ return self._send_app_call(lambda c: c.add_app_delete)(params, send_params)
488
+
489
+ def app_call(
490
+ self, params: AppCallParams, send_params: SendParams | None = None
491
+ ) -> SendAppTransactionResult[ABIReturn]:
492
+ """Call an application.
493
+
494
+ :param params: Application call parameters
495
+ :param send_params: Send parameters
496
+ :return: Result containing any ABI return value
497
+ """
498
+ return self._send_app_call(lambda c: c.add_app_call)(params, send_params)
499
+
500
+ def app_create_method_call(
501
+ self, params: AppCreateMethodCallParams, send_params: SendParams | None = None
502
+ ) -> SendAppCreateTransactionResult[ABIReturn]:
503
+ """Call an application's create method.
504
+
505
+ :param params: Method call parameters for application creation
506
+ :param send_params: Send parameters
507
+ :return: Result containing the new application ID and address
508
+ """
509
+ return self._send_app_create_call(lambda c: c.add_app_create_method_call)(params, send_params)
510
+
511
+ def app_update_method_call(
512
+ self, params: AppUpdateMethodCallParams, send_params: SendParams | None = None
513
+ ) -> SendAppUpdateTransactionResult[ABIReturn]:
514
+ """Call an application's update method.
515
+
516
+ :param params: Method call parameters for application update
517
+ :param send_params: Send parameters
518
+ :return: Result containing the compiled programs
519
+ """
520
+ return self._send_app_update_call(lambda c: c.add_app_update_method_call)(params, send_params)
521
+
522
+ def app_delete_method_call(
523
+ self, params: AppDeleteMethodCallParams, send_params: SendParams | None = None
524
+ ) -> SendAppTransactionResult[ABIReturn]:
525
+ """Call an application's delete method.
526
+
527
+ :param params: Method call parameters for application deletion
528
+ :param send_params: Send parameters
529
+ :return: Result of the deletion transaction
530
+ """
531
+ return self._send_app_call(lambda c: c.add_app_delete_method_call)(params, send_params)
532
+
533
+ def app_call_method_call(
534
+ self, params: AppCallMethodCallParams, send_params: SendParams | None = None
535
+ ) -> SendAppTransactionResult[ABIReturn]:
536
+ """Call an application's call method.
537
+
538
+ :param params: Method call parameters
539
+ :param send_params: Send parameters
540
+ :return: Result containing any ABI return value
541
+ """
542
+ return self._send_app_call(lambda c: c.add_app_call_method_call)(params, send_params)
543
+
544
+ def online_key_registration(
545
+ self, params: OnlineKeyRegistrationParams, send_params: SendParams | None = None
546
+ ) -> SendSingleTransactionResult:
547
+ """Register an online key.
548
+
549
+ :param params: Key registration parameters
550
+ :param send_params: Send parameters
551
+ :return: Result of the registration transaction
552
+ """
553
+ return self._send(
554
+ lambda c: c.add_online_key_registration,
555
+ pre_log=lambda params, transaction: (
556
+ f"Registering online key for {params.sender} via transaction {transaction.get_txid()}"
557
+ ),
558
+ )(params, send_params)
559
+
560
+ def offline_key_registration(
561
+ self, params: OfflineKeyRegistrationParams, send_params: SendParams | None = None
562
+ ) -> SendSingleTransactionResult:
563
+ """Register an offline key.
564
+
565
+ :param params: Key registration parameters
566
+ :param send_params: Send parameters
567
+ :return: Result of the registration transaction
568
+ """
569
+ return self._send(
570
+ lambda c: c.add_offline_key_registration,
571
+ pre_log=lambda params, transaction: (
572
+ f"Registering offline key for {params.sender} via transaction {transaction.get_txid()}"
573
+ ),
574
+ )(params, send_params)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: algokit-utils
3
- Version: 3.0.0b1
3
+ Version: 3.0.0b3
4
4
  Summary: Utilities for Algorand development for use by AlgoKit
5
5
  License: MIT
6
6
  Author: Algorand Foundation
@@ -11,23 +11,24 @@ Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: deprecated (>=1.2.14,<2.0.0)
15
- Requires-Dist: httpx (>=0.23.1,<0.24.0)
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: httpx (>=0.28,<0.29)
16
16
  Requires-Dist: py-algorand-sdk (>=2.4.0,<3.0.0)
17
+ Requires-Dist: typing-extensions (>=4.6.0)
17
18
  Description-Content-Type: text/markdown
18
19
 
19
20
  # AlgoKit Python Utilities
20
21
 
21
- A set of core Algorand utilities written in Python and released via PyPi that make it easier to build solutions on Algorand.
22
+ A set of core Algorand utilities written in Python and released via PyPi that make it easier to build solutions on Algorand.
22
23
  This project is part of [AlgoKit](https://github.com/algorandfoundation/algokit-cli).
23
24
 
24
- The goal of this library is to provide intuitive, productive utility functions that make it easier, quicker and safer to build applications on Algorand.
25
+ The goal of this library is to provide intuitive, productive utility functions that make it easier, quicker and safer to build applications on Algorand.
25
26
  Largely these functions wrap the underlying Algorand SDK, but provide a higher level interface with sensible defaults and capabilities for common tasks.
26
27
 
27
28
  > **Note**
28
29
  > If you prefer TypeScript there's an equivalent [TypeScript utility library](https://github.com/algorandfoundation/algokit-utils-ts).
29
30
 
30
- [Install](https://github.com/algorandfoundation/algokit-utils-py#install) | [Documentation](https://algorandfoundation.github.io/algokit-utils-py/html/index.html)
31
+ [Install](https://github.com/algorandfoundation/algokit-utils-py#install) | [Documentation](https://algorandfoundation.github.io/algokit-utils-py)
31
32
 
32
33
  ## Install
33
34
 
@@ -37,13 +38,17 @@ This library can be installed using pip, e.g.:
37
38
  pip install algokit-utils
38
39
  ```
39
40
 
41
+ ## Migration from `v2.x` to `v3.x`
42
+
43
+ Refer to the [v3 migration](./docs/source/v3-migration-guide.md) for more information on how to migrate to latest version of `algokit-utils-py`.
44
+
40
45
  ## Guiding principles
41
46
 
42
47
  This library follows the [Guiding Principles of AlgoKit](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md#guiding-principles).
43
48
 
44
49
  ## Contributing
45
50
 
46
- This is an open source project managed by the Algorand Foundation.
51
+ This is an open source project managed by the Algorand Foundation.
47
52
  See the [AlgoKit contributing page](https://github.com/algorandfoundation/algokit-cli/blob/main/CONTRIBUTING.MD) to learn about making improvements.
48
53
 
49
54
  To successfully run the tests in this repository you need to be running LocalNet via [AlgoKit](https://github.com/algorandfoundation/algokit-cli):