algokit-utils 3.0.0b10__py3-none-any.whl → 3.0.0b12__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/_legacy_v2/_ensure_funded.py +3 -7
- algokit_utils/_legacy_v2/_transfer.py +4 -2
- algokit_utils/_legacy_v2/account.py +5 -5
- algokit_utils/_legacy_v2/deploy.py +1 -1
- algokit_utils/_legacy_v2/network_clients.py +10 -6
- algokit_utils/accounts/account_manager.py +71 -67
- algokit_utils/algorand.py +105 -11
- algokit_utils/application_specification.py +1 -1
- algokit_utils/applications/abi.py +8 -12
- algokit_utils/applications/app_client.py +132 -44
- algokit_utils/applications/app_deployer.py +93 -2
- algokit_utils/applications/app_factory.py +315 -1
- algokit_utils/applications/app_manager.py +110 -2
- algokit_utils/applications/app_spec/arc56.py +131 -190
- algokit_utils/assets/asset_manager.py +47 -31
- algokit_utils/clients/client_manager.py +76 -0
- algokit_utils/clients/dispenser_api_client.py +32 -3
- algokit_utils/models/application.py +30 -0
- algokit_utils/models/state.py +9 -0
- algokit_utils/transactions/transaction_composer.py +366 -182
- algokit_utils/transactions/transaction_creator.py +550 -18
- algokit_utils/transactions/transaction_sender.py +645 -0
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b12.dist-info}/METADATA +1 -1
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b12.dist-info}/RECORD +26 -26
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b12.dist-info}/WHEEL +1 -1
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b12.dist-info}/LICENSE +0 -0
|
@@ -123,30 +123,56 @@ class AppDeployParams:
|
|
|
123
123
|
"""Parameters for deploying an app"""
|
|
124
124
|
|
|
125
125
|
metadata: AppDeploymentMetaData
|
|
126
|
+
"""The deployment metadata"""
|
|
126
127
|
deploy_time_params: TealTemplateParams | None = None
|
|
128
|
+
"""Optional template parameters to use during compilation"""
|
|
127
129
|
on_schema_break: (Literal["replace", "fail", "append"] | OnSchemaBreak) | None = None
|
|
130
|
+
"""Optional on schema break action"""
|
|
128
131
|
on_update: (Literal["update", "replace", "fail", "append"] | OnUpdate) | None = None
|
|
132
|
+
"""Optional on update action"""
|
|
129
133
|
create_params: AppCreateParams | AppCreateMethodCallParams
|
|
134
|
+
"""The creation parameters"""
|
|
130
135
|
update_params: AppUpdateParams | AppUpdateMethodCallParams
|
|
136
|
+
"""The update parameters"""
|
|
131
137
|
delete_params: AppDeleteParams | AppDeleteMethodCallParams
|
|
138
|
+
"""The deletion parameters"""
|
|
132
139
|
existing_deployments: ApplicationLookup | None = None
|
|
140
|
+
"""Optional existing deployments"""
|
|
133
141
|
ignore_cache: bool = False
|
|
142
|
+
"""Whether to ignore the cache"""
|
|
134
143
|
max_fee: int | None = None
|
|
144
|
+
"""Optional maximum fee"""
|
|
135
145
|
send_params: SendParams | None = None
|
|
146
|
+
"""Optional send parameters"""
|
|
136
147
|
|
|
137
148
|
|
|
138
149
|
# Union type for all possible deploy results
|
|
139
150
|
@dataclass(frozen=True)
|
|
140
151
|
class AppDeployResult:
|
|
152
|
+
"""The result of a deployment"""
|
|
153
|
+
|
|
141
154
|
app: ApplicationMetaData
|
|
155
|
+
"""The application metadata"""
|
|
142
156
|
operation_performed: OperationPerformed
|
|
157
|
+
"""The operation performed"""
|
|
143
158
|
create_result: SendAppCreateTransactionResult[ABIReturn] | None = None
|
|
159
|
+
"""The create result"""
|
|
144
160
|
update_result: SendAppUpdateTransactionResult[ABIReturn] | None = None
|
|
161
|
+
"""The update result"""
|
|
145
162
|
delete_result: SendAppTransactionResult[ABIReturn] | None = None
|
|
163
|
+
"""The delete result"""
|
|
146
164
|
|
|
147
165
|
|
|
148
166
|
class AppDeployer:
|
|
149
|
-
"""Manages deployment and deployment metadata of applications
|
|
167
|
+
"""Manages deployment and deployment metadata of applications
|
|
168
|
+
|
|
169
|
+
:param app_manager: The app manager to use
|
|
170
|
+
:param transaction_sender: The transaction sender to use
|
|
171
|
+
:param indexer: The indexer to use
|
|
172
|
+
|
|
173
|
+
:example:
|
|
174
|
+
>>> deployer = AppDeployer(app_manager, transaction_sender, indexer)
|
|
175
|
+
"""
|
|
150
176
|
|
|
151
177
|
def __init__(
|
|
152
178
|
self,
|
|
@@ -160,6 +186,56 @@ class AppDeployer:
|
|
|
160
186
|
self._app_lookups: dict[str, ApplicationLookup] = {}
|
|
161
187
|
|
|
162
188
|
def deploy(self, deployment: AppDeployParams) -> AppDeployResult:
|
|
189
|
+
"""Idempotently deploy (create if not exists, update if changed) an app against the given name for the given
|
|
190
|
+
creator account, including deploy-time TEAL template placeholder substitutions (if specified).
|
|
191
|
+
|
|
192
|
+
To understand the architecture decisions behind this functionality please see
|
|
193
|
+
https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md
|
|
194
|
+
|
|
195
|
+
**Note:** When using the return from this function be sure to check `operation_performed` to get access to
|
|
196
|
+
return properties like `transaction`, `confirmation` and `delete_result`.
|
|
197
|
+
|
|
198
|
+
**Note:** if there is a breaking state schema change to an existing app (and `on_schema_break` is set to
|
|
199
|
+
`'replace'`) the existing app will be deleted and re-created.
|
|
200
|
+
|
|
201
|
+
**Note:** if there is an update (different TEAL code) to an existing app (and `on_update` is set to `'replace'`)
|
|
202
|
+
the existing app will be deleted and re-created.
|
|
203
|
+
|
|
204
|
+
:param deployment: The arguments to control the app deployment
|
|
205
|
+
:returns: The result of the deployment
|
|
206
|
+
:raises ValueError: If the app spec format is invalid
|
|
207
|
+
|
|
208
|
+
:example:
|
|
209
|
+
>>> deployer.deploy(AppDeployParams(
|
|
210
|
+
... create_params=AppCreateParams(
|
|
211
|
+
... sender='SENDER_ADDRESS',
|
|
212
|
+
... approval_program='APPROVAL PROGRAM',
|
|
213
|
+
... clear_state_program='CLEAR PROGRAM',
|
|
214
|
+
... schema={
|
|
215
|
+
... 'global_byte_slices': 0,
|
|
216
|
+
... 'global_ints': 0,
|
|
217
|
+
... 'local_byte_slices': 0,
|
|
218
|
+
... 'local_ints': 0
|
|
219
|
+
... }
|
|
220
|
+
... ),
|
|
221
|
+
... update_params=AppUpdateParams(
|
|
222
|
+
... sender='SENDER_ADDRESS'
|
|
223
|
+
... ),
|
|
224
|
+
... delete_params=AppDeleteParams(
|
|
225
|
+
... sender='SENDER_ADDRESS'
|
|
226
|
+
... ),
|
|
227
|
+
... metadata=AppDeploymentMetaData(
|
|
228
|
+
... name='my_app',
|
|
229
|
+
... version='2.0',
|
|
230
|
+
... updatable=False,
|
|
231
|
+
... deletable=False
|
|
232
|
+
... ),
|
|
233
|
+
... on_schema_break=OnSchemaBreak.AppendApp,
|
|
234
|
+
... on_update=OnUpdate.AppendApp
|
|
235
|
+
... )
|
|
236
|
+
... )
|
|
237
|
+
"""
|
|
238
|
+
|
|
163
239
|
# Create new instances with updated notes
|
|
164
240
|
send_params = deployment.send_params or SendParams()
|
|
165
241
|
suppress_log = send_params.get("suppress_log") or False
|
|
@@ -569,7 +645,22 @@ class AppDeployer:
|
|
|
569
645
|
lookup.apps[app_metadata.name] = app_metadata
|
|
570
646
|
|
|
571
647
|
def get_creator_apps_by_name(self, *, creator_address: str, ignore_cache: bool = False) -> ApplicationLookup:
|
|
572
|
-
"""
|
|
648
|
+
"""Returns a lookup of name => app metadata (id, address, ...metadata) for all apps created by the given account
|
|
649
|
+
that have an [ARC-2](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md) `AppDeployNote` as
|
|
650
|
+
the transaction note of the app creation transaction.
|
|
651
|
+
|
|
652
|
+
This function caches the result for the given creator account so that subsequent calls won't require an indexer
|
|
653
|
+
lookup.
|
|
654
|
+
|
|
655
|
+
If the `AppManager` instance wasn't created with an indexer client, this function will throw an error.
|
|
656
|
+
|
|
657
|
+
:param creator_address: The address of the account that is the creator of the apps you want to search for
|
|
658
|
+
:param ignore_cache: Whether or not to ignore the cache and force a lookup, default: use the cache
|
|
659
|
+
:returns: A name-based lookup of the app metadata
|
|
660
|
+
:raises ValueError: If the app spec format is invalid
|
|
661
|
+
:example:
|
|
662
|
+
>>> result = await deployer.get_creator_apps_by_name(creator)
|
|
663
|
+
"""
|
|
573
664
|
|
|
574
665
|
if not ignore_cache and creator_address in self._app_lookups:
|
|
575
666
|
return self._app_lookups[creator_address]
|
|
@@ -131,10 +131,15 @@ class AppFactoryDeployResult:
|
|
|
131
131
|
"""Result from deploying an application via AppFactory"""
|
|
132
132
|
|
|
133
133
|
app: ApplicationMetaData
|
|
134
|
+
"""The application metadata"""
|
|
134
135
|
operation_performed: OperationPerformed
|
|
136
|
+
"""The operation performed"""
|
|
135
137
|
create_result: SendAppCreateFactoryTransactionResult | None = None
|
|
138
|
+
"""The create result"""
|
|
136
139
|
update_result: SendAppUpdateFactoryTransactionResult | None = None
|
|
140
|
+
"""The update result"""
|
|
137
141
|
delete_result: SendAppFactoryTransactionResult | None = None
|
|
142
|
+
"""The delete result"""
|
|
138
143
|
|
|
139
144
|
@classmethod
|
|
140
145
|
def from_deploy_result(
|
|
@@ -144,6 +149,16 @@ class AppFactoryDeployResult:
|
|
|
144
149
|
app_spec: Arc56Contract,
|
|
145
150
|
app_compilation_data: AppClientCompilationResult | None = None,
|
|
146
151
|
) -> Self:
|
|
152
|
+
"""
|
|
153
|
+
Construct an AppFactoryDeployResult from a deployment result.
|
|
154
|
+
|
|
155
|
+
:param response: The deployment response.
|
|
156
|
+
:param deploy_params: The deployment parameters.
|
|
157
|
+
:param app_spec: The application specification.
|
|
158
|
+
:param app_compilation_data: Optional app compilation data.
|
|
159
|
+
:return: An instance of AppFactoryDeployResult.
|
|
160
|
+
"""
|
|
161
|
+
|
|
147
162
|
def to_factory_result(
|
|
148
163
|
response_data: SendAppTransactionResult[ABIReturn]
|
|
149
164
|
| SendAppCreateTransactionResult
|
|
@@ -192,6 +207,11 @@ class AppFactoryDeployResult:
|
|
|
192
207
|
|
|
193
208
|
|
|
194
209
|
class _BareParamsBuilder:
|
|
210
|
+
"""The bare params builder.
|
|
211
|
+
|
|
212
|
+
:param factory: The AppFactory instance.
|
|
213
|
+
"""
|
|
214
|
+
|
|
195
215
|
def __init__(self, factory: "AppFactory") -> None:
|
|
196
216
|
self._factory = factory
|
|
197
217
|
self._algorand = factory._algorand
|
|
@@ -199,6 +219,13 @@ class _BareParamsBuilder:
|
|
|
199
219
|
def create(
|
|
200
220
|
self, params: AppFactoryCreateParams | None = None, compilation_params: AppClientCompilationParams | None = None
|
|
201
221
|
) -> AppCreateParams:
|
|
222
|
+
"""
|
|
223
|
+
Create AppCreateParams using the provided parameters and compilation settings.
|
|
224
|
+
|
|
225
|
+
:param params: Optional AppFactoryCreateParams instance.
|
|
226
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
227
|
+
:return: An instance of AppCreateParams.
|
|
228
|
+
"""
|
|
202
229
|
base_params = params or AppFactoryCreateParams()
|
|
203
230
|
compiled = self._factory.compile(compilation_params)
|
|
204
231
|
|
|
@@ -225,6 +252,12 @@ class _BareParamsBuilder:
|
|
|
225
252
|
)
|
|
226
253
|
|
|
227
254
|
def deploy_update(self, params: AppClientBareCallParams | None = None) -> AppUpdateParams:
|
|
255
|
+
"""
|
|
256
|
+
Create AppUpdateParams for an update operation.
|
|
257
|
+
|
|
258
|
+
:param params: Optional AppClientBareCallParams instance.
|
|
259
|
+
:return: An instance of AppUpdateParams.
|
|
260
|
+
"""
|
|
228
261
|
return AppUpdateParams(
|
|
229
262
|
**{
|
|
230
263
|
**{
|
|
@@ -244,6 +277,12 @@ class _BareParamsBuilder:
|
|
|
244
277
|
)
|
|
245
278
|
|
|
246
279
|
def deploy_delete(self, params: AppClientBareCallParams | None = None) -> AppDeleteParams:
|
|
280
|
+
"""
|
|
281
|
+
Create AppDeleteParams for a delete operation.
|
|
282
|
+
|
|
283
|
+
:param params: Optional AppClientBareCallParams instance.
|
|
284
|
+
:return: An instance of AppDeleteParams.
|
|
285
|
+
"""
|
|
247
286
|
return AppDeleteParams(
|
|
248
287
|
**{
|
|
249
288
|
**{
|
|
@@ -262,17 +301,34 @@ class _BareParamsBuilder:
|
|
|
262
301
|
|
|
263
302
|
|
|
264
303
|
class _MethodParamsBuilder:
|
|
304
|
+
"""The method params builder.
|
|
305
|
+
|
|
306
|
+
:param factory: The AppFactory instance.
|
|
307
|
+
"""
|
|
308
|
+
|
|
265
309
|
def __init__(self, factory: "AppFactory") -> None:
|
|
266
310
|
self._factory = factory
|
|
267
311
|
self._bare = _BareParamsBuilder(factory)
|
|
268
312
|
|
|
269
313
|
@property
|
|
270
314
|
def bare(self) -> _BareParamsBuilder:
|
|
315
|
+
"""
|
|
316
|
+
Get the bare parameters builder.
|
|
317
|
+
|
|
318
|
+
:return: The _BareParamsBuilder instance.
|
|
319
|
+
"""
|
|
271
320
|
return self._bare
|
|
272
321
|
|
|
273
322
|
def create(
|
|
274
323
|
self, params: AppFactoryCreateMethodCallParams, compilation_params: AppClientCompilationParams | None = None
|
|
275
324
|
) -> AppCreateMethodCallParams:
|
|
325
|
+
"""
|
|
326
|
+
Create AppCreateMethodCallParams using the provided parameters and compilation settings.
|
|
327
|
+
|
|
328
|
+
:param params: AppFactoryCreateMethodCallParams instance.
|
|
329
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
330
|
+
:return: An instance of AppCreateMethodCallParams.
|
|
331
|
+
"""
|
|
276
332
|
compiled = self._factory.compile(compilation_params)
|
|
277
333
|
|
|
278
334
|
return AppCreateMethodCallParams(
|
|
@@ -303,6 +359,12 @@ class _MethodParamsBuilder:
|
|
|
303
359
|
)
|
|
304
360
|
|
|
305
361
|
def deploy_update(self, params: AppClientMethodCallParams) -> AppUpdateMethodCallParams:
|
|
362
|
+
"""
|
|
363
|
+
Create AppUpdateMethodCallParams for an update operation.
|
|
364
|
+
|
|
365
|
+
:param params: AppClientMethodCallParams instance.
|
|
366
|
+
:return: An instance of AppUpdateMethodCallParams.
|
|
367
|
+
"""
|
|
306
368
|
return AppUpdateMethodCallParams(
|
|
307
369
|
**{
|
|
308
370
|
**{
|
|
@@ -324,6 +386,12 @@ class _MethodParamsBuilder:
|
|
|
324
386
|
)
|
|
325
387
|
|
|
326
388
|
def deploy_delete(self, params: AppClientMethodCallParams) -> AppDeleteMethodCallParams:
|
|
389
|
+
"""
|
|
390
|
+
Create AppDeleteMethodCallParams for a delete operation.
|
|
391
|
+
|
|
392
|
+
:param params: AppClientMethodCallParams instance.
|
|
393
|
+
:return: An instance of AppDeleteMethodCallParams.
|
|
394
|
+
"""
|
|
327
395
|
return AppDeleteMethodCallParams(
|
|
328
396
|
**{
|
|
329
397
|
**{
|
|
@@ -344,27 +412,61 @@ class _MethodParamsBuilder:
|
|
|
344
412
|
|
|
345
413
|
|
|
346
414
|
class _AppFactoryBareCreateTransactionAccessor:
|
|
415
|
+
"""Initialize the bare create transaction accessor.
|
|
416
|
+
|
|
417
|
+
:param factory: The AppFactory instance.
|
|
418
|
+
"""
|
|
419
|
+
|
|
347
420
|
def __init__(self, factory: "AppFactory") -> None:
|
|
348
421
|
self._factory = factory
|
|
349
422
|
|
|
350
423
|
def create(self, params: AppFactoryCreateParams | None = None) -> Transaction:
|
|
424
|
+
"""
|
|
425
|
+
Create a transaction for app creation.
|
|
426
|
+
|
|
427
|
+
:param params: Optional AppFactoryCreateParams instance.
|
|
428
|
+
:return: A Transaction instance.
|
|
429
|
+
"""
|
|
351
430
|
return self._factory._algorand.create_transaction.app_create(self._factory.params.bare.create(params))
|
|
352
431
|
|
|
353
432
|
|
|
354
433
|
class _TransactionCreator:
|
|
434
|
+
"""
|
|
435
|
+
The transaction creator.
|
|
436
|
+
|
|
437
|
+
:param factory: The AppFactory instance.
|
|
438
|
+
"""
|
|
439
|
+
|
|
355
440
|
def __init__(self, factory: "AppFactory") -> None:
|
|
356
441
|
self._factory = factory
|
|
357
442
|
self._bare = _AppFactoryBareCreateTransactionAccessor(factory)
|
|
358
443
|
|
|
359
444
|
@property
|
|
360
445
|
def bare(self) -> _AppFactoryBareCreateTransactionAccessor:
|
|
446
|
+
"""
|
|
447
|
+
Get the bare create transaction accessor.
|
|
448
|
+
|
|
449
|
+
:return: The _AppFactoryBareCreateTransactionAccessor instance.
|
|
450
|
+
"""
|
|
361
451
|
return self._bare
|
|
362
452
|
|
|
363
453
|
def create(self, params: AppFactoryCreateMethodCallParams) -> BuiltTransactions:
|
|
454
|
+
"""
|
|
455
|
+
Create built transactions for an app method call.
|
|
456
|
+
|
|
457
|
+
:param params: AppFactoryCreateMethodCallParams instance.
|
|
458
|
+
:return: A BuiltTransactions instance.
|
|
459
|
+
"""
|
|
364
460
|
return self._factory._algorand.create_transaction.app_create_method_call(self._factory.params.create(params))
|
|
365
461
|
|
|
366
462
|
|
|
367
463
|
class _AppFactoryBareSendAccessor:
|
|
464
|
+
"""
|
|
465
|
+
The bare send accessor.
|
|
466
|
+
|
|
467
|
+
:param factory: The AppFactory instance.
|
|
468
|
+
"""
|
|
469
|
+
|
|
368
470
|
def __init__(self, factory: "AppFactory") -> None:
|
|
369
471
|
self._factory = factory
|
|
370
472
|
self._algorand = factory._algorand
|
|
@@ -375,6 +477,14 @@ class _AppFactoryBareSendAccessor:
|
|
|
375
477
|
send_params: SendParams | None = None,
|
|
376
478
|
compilation_params: AppClientCompilationParams | None = None,
|
|
377
479
|
) -> tuple[AppClient, SendAppCreateTransactionResult]:
|
|
480
|
+
"""
|
|
481
|
+
Send an app creation transaction and return the app client along with the transaction result.
|
|
482
|
+
|
|
483
|
+
:param params: Optional AppFactoryCreateParams instance.
|
|
484
|
+
:param send_params: Optional SendParams instance.
|
|
485
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
486
|
+
:return: A tuple containing the AppClient and SendAppCreateTransactionResult.
|
|
487
|
+
"""
|
|
378
488
|
compilation_params = compilation_params or AppClientCompilationParams()
|
|
379
489
|
compilation_params["updatable"] = (
|
|
380
490
|
compilation_params.get("updatable")
|
|
@@ -420,6 +530,12 @@ class _AppFactoryBareSendAccessor:
|
|
|
420
530
|
|
|
421
531
|
|
|
422
532
|
class _TransactionSender:
|
|
533
|
+
"""
|
|
534
|
+
The transaction sender.
|
|
535
|
+
|
|
536
|
+
:param factory: The AppFactory instance.
|
|
537
|
+
"""
|
|
538
|
+
|
|
423
539
|
def __init__(self, factory: "AppFactory") -> None:
|
|
424
540
|
self._factory = factory
|
|
425
541
|
self._algorand = factory._algorand
|
|
@@ -427,6 +543,11 @@ class _TransactionSender:
|
|
|
427
543
|
|
|
428
544
|
@property
|
|
429
545
|
def bare(self) -> _AppFactoryBareSendAccessor:
|
|
546
|
+
"""
|
|
547
|
+
Get the bare send accessor.
|
|
548
|
+
|
|
549
|
+
:return: The _AppFactoryBareSendAccessor instance.
|
|
550
|
+
"""
|
|
430
551
|
return self._bare
|
|
431
552
|
|
|
432
553
|
def create(
|
|
@@ -435,6 +556,14 @@ class _TransactionSender:
|
|
|
435
556
|
send_params: SendParams | None = None,
|
|
436
557
|
compilation_params: AppClientCompilationParams | None = None,
|
|
437
558
|
) -> tuple[AppClient, AppFactoryCreateMethodCallResult[Arc56ReturnValueType]]:
|
|
559
|
+
"""
|
|
560
|
+
Send an app creation method call and return the app client along with the method call result.
|
|
561
|
+
|
|
562
|
+
:param params: AppFactoryCreateMethodCallParams instance.
|
|
563
|
+
:param send_params: Optional SendParams instance.
|
|
564
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
565
|
+
:return: A tuple containing the AppClient and AppFactoryCreateMethodCallResult.
|
|
566
|
+
"""
|
|
438
567
|
compilation_params = compilation_params or AppClientCompilationParams()
|
|
439
568
|
compilation_params["updatable"] = (
|
|
440
569
|
compilation_params.get("updatable")
|
|
@@ -485,6 +614,20 @@ class _TransactionSender:
|
|
|
485
614
|
|
|
486
615
|
|
|
487
616
|
class AppFactory:
|
|
617
|
+
"""ARC-56/ARC-32 app factory that, for a given app spec, allows you to create
|
|
618
|
+
and deploy one or more app instances and to create one or more app clients
|
|
619
|
+
to interact with those (or other) app instances.
|
|
620
|
+
|
|
621
|
+
:param params: The parameters for the factory
|
|
622
|
+
|
|
623
|
+
:example:
|
|
624
|
+
>>> factory = AppFactory(AppFactoryParams(
|
|
625
|
+
>>> algorand=AlgorandClient.mainnet(),
|
|
626
|
+
>>> app_spec=app_spec,
|
|
627
|
+
>>> )
|
|
628
|
+
>>> )
|
|
629
|
+
"""
|
|
630
|
+
|
|
488
631
|
def __init__(self, params: AppFactoryParams) -> None:
|
|
489
632
|
self._app_spec = AppClient.normalise_app_spec(params.app_spec)
|
|
490
633
|
self._app_name = params.app_name or self._app_spec.name
|
|
@@ -505,26 +648,67 @@ class AppFactory:
|
|
|
505
648
|
|
|
506
649
|
@property
|
|
507
650
|
def app_name(self) -> str:
|
|
651
|
+
"""The name of the app"""
|
|
508
652
|
return self._app_name
|
|
509
653
|
|
|
510
654
|
@property
|
|
511
655
|
def app_spec(self) -> Arc56Contract:
|
|
656
|
+
"""The app spec"""
|
|
512
657
|
return self._app_spec
|
|
513
658
|
|
|
514
659
|
@property
|
|
515
660
|
def algorand(self) -> AlgorandClient:
|
|
661
|
+
"""The algorand client"""
|
|
516
662
|
return self._algorand
|
|
517
663
|
|
|
518
664
|
@property
|
|
519
665
|
def params(self) -> _MethodParamsBuilder:
|
|
666
|
+
"""Get parameters to create transactions (create and deploy related calls) for the current app.
|
|
667
|
+
|
|
668
|
+
A good mental model for this is that these parameters represent a deferred transaction creation.
|
|
669
|
+
|
|
670
|
+
:example: Create a transaction in the future using Algorand Client
|
|
671
|
+
>>> create_app_params = app_factory.params.create(
|
|
672
|
+
... AppFactoryCreateMethodCallParams(
|
|
673
|
+
... method='create_method',
|
|
674
|
+
... args=[123, 'hello']
|
|
675
|
+
... )
|
|
676
|
+
... )
|
|
677
|
+
>>> # ...
|
|
678
|
+
>>> algorand.send.app_create_method_call(create_app_params)
|
|
679
|
+
|
|
680
|
+
:example: Define a nested transaction as an ABI argument
|
|
681
|
+
>>> create_app_params = appFactory.params.create(
|
|
682
|
+
... AppFactoryCreateMethodCallParams(
|
|
683
|
+
... method='create_method',
|
|
684
|
+
... args=[123, 'hello']
|
|
685
|
+
... )
|
|
686
|
+
... )
|
|
687
|
+
>>> app_client.send.call(
|
|
688
|
+
... AppClientMethodCallParams(
|
|
689
|
+
... method='my_method',
|
|
690
|
+
... args=[create_app_params]
|
|
691
|
+
... )
|
|
692
|
+
... )
|
|
693
|
+
"""
|
|
520
694
|
return self._params_accessor
|
|
521
695
|
|
|
522
696
|
@property
|
|
523
697
|
def send(self) -> _TransactionSender:
|
|
698
|
+
"""
|
|
699
|
+
Get the transaction sender.
|
|
700
|
+
|
|
701
|
+
:return: The _TransactionSender instance.
|
|
702
|
+
"""
|
|
524
703
|
return self._send_accessor
|
|
525
704
|
|
|
526
705
|
@property
|
|
527
706
|
def create_transaction(self) -> _TransactionCreator:
|
|
707
|
+
"""
|
|
708
|
+
Get the transaction creator.
|
|
709
|
+
|
|
710
|
+
:return: The _TransactionCreator instance.
|
|
711
|
+
"""
|
|
528
712
|
return self._create_transaction_accessor
|
|
529
713
|
|
|
530
714
|
def deploy(
|
|
@@ -541,7 +725,58 @@ class AppFactory:
|
|
|
541
725
|
send_params: SendParams | None = None,
|
|
542
726
|
compilation_params: AppClientCompilationParams | None = None,
|
|
543
727
|
) -> tuple[AppClient, AppFactoryDeployResult]:
|
|
544
|
-
"""
|
|
728
|
+
"""Idempotently deploy (create if not exists, update if changed) an app against the given name for the given
|
|
729
|
+
creator account, including deploy-time TEAL template placeholder substitutions (if specified).
|
|
730
|
+
|
|
731
|
+
**Note:** When using the return from this function be sure to check `operationPerformed` to get access to
|
|
732
|
+
various return properties like `transaction`, `confirmation` and `deleteResult`.
|
|
733
|
+
|
|
734
|
+
**Note:** if there is a breaking state schema change to an existing app (and `onSchemaBreak` is set to
|
|
735
|
+
`'replace'`) the existing app will be deleted and re-created.
|
|
736
|
+
|
|
737
|
+
**Note:** if there is an update (different TEAL code) to an existing app (and `onUpdate` is set to
|
|
738
|
+
`'replace'`) the existing app will be deleted and re-created.
|
|
739
|
+
|
|
740
|
+
:param on_update: The action to take if there is an update to the app
|
|
741
|
+
:param on_schema_break: The action to take if there is a breaking state schema change to the app
|
|
742
|
+
:param create_params: The arguments to create the app
|
|
743
|
+
:param update_params: The arguments to update the app
|
|
744
|
+
:param delete_params: The arguments to delete the app
|
|
745
|
+
:param existing_deployments: The existing deployments to use
|
|
746
|
+
:param ignore_cache: Whether to ignore the cache
|
|
747
|
+
:param app_name: The name of the app
|
|
748
|
+
:param send_params: The parameters for the send call
|
|
749
|
+
:param compilation_params: The parameters for the compilation
|
|
750
|
+
:returns: The app client and the result of the deployment
|
|
751
|
+
|
|
752
|
+
:example:
|
|
753
|
+
>>> app_client, result = factory.deploy({
|
|
754
|
+
>>> create_params=AppClientMethodCallCreateParams(
|
|
755
|
+
>>> sender='SENDER_ADDRESS',
|
|
756
|
+
>>> approval_program='APPROVAL PROGRAM',
|
|
757
|
+
>>> clear_state_program='CLEAR PROGRAM',
|
|
758
|
+
>>> schema={
|
|
759
|
+
>>> "global_byte_slices": 0,
|
|
760
|
+
>>> "global_ints": 0,
|
|
761
|
+
>>> "local_byte_slices": 0,
|
|
762
|
+
>>> "local_ints": 0
|
|
763
|
+
>>> }
|
|
764
|
+
>>> ),
|
|
765
|
+
>>> update_params=AppClientMethodCallParams(
|
|
766
|
+
>>> sender='SENDER_ADDRESS'
|
|
767
|
+
>>> ),
|
|
768
|
+
>>> delete_params=AppClientMethodCallParams(
|
|
769
|
+
>>> sender='SENDER_ADDRESS'
|
|
770
|
+
>>> ),
|
|
771
|
+
>>> compilation_params=AppClientCompilationParams(
|
|
772
|
+
>>> updatable=False,
|
|
773
|
+
>>> deletable=False
|
|
774
|
+
>>> ),
|
|
775
|
+
>>> app_name='my_app',
|
|
776
|
+
>>> on_schema_break=OnSchemaBreak.AppendApp,
|
|
777
|
+
>>> on_update=OnUpdate.AppendApp
|
|
778
|
+
>>> })
|
|
779
|
+
"""
|
|
545
780
|
# Resolve control parameters with factory defaults
|
|
546
781
|
send_params = send_params or SendParams()
|
|
547
782
|
compilation_params = compilation_params or AppClientCompilationParams()
|
|
@@ -650,6 +885,19 @@ class AppFactory:
|
|
|
650
885
|
approval_source_map: SourceMap | None = None,
|
|
651
886
|
clear_source_map: SourceMap | None = None,
|
|
652
887
|
) -> AppClient:
|
|
888
|
+
"""Returns a new `AppClient` client for an app instance of the given ID.
|
|
889
|
+
|
|
890
|
+
:param app_id: The id of the app
|
|
891
|
+
:param app_name: The name of the app
|
|
892
|
+
:param default_sender: The default sender address
|
|
893
|
+
:param default_signer: The default signer
|
|
894
|
+
:param approval_source_map: The approval source map
|
|
895
|
+
:param clear_source_map: The clear source map
|
|
896
|
+
:return AppClient: The app client
|
|
897
|
+
|
|
898
|
+
:example:
|
|
899
|
+
>>> app_client = factory.get_app_client_by_id(app_id=123)
|
|
900
|
+
"""
|
|
653
901
|
return AppClient(
|
|
654
902
|
AppClientParams(
|
|
655
903
|
app_id=app_id,
|
|
@@ -674,6 +922,25 @@ class AppFactory:
|
|
|
674
922
|
approval_source_map: SourceMap | None = None,
|
|
675
923
|
clear_source_map: SourceMap | None = None,
|
|
676
924
|
) -> AppClient:
|
|
925
|
+
"""Returns a new `AppClient` client, resolving the app by creator address and name
|
|
926
|
+
using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note).
|
|
927
|
+
|
|
928
|
+
:param creator_address: The creator address
|
|
929
|
+
:param app_name: The name of the app
|
|
930
|
+
:param default_sender: The default sender address
|
|
931
|
+
:param default_signer: The default signer
|
|
932
|
+
:param ignore_cache: Whether to ignore the cache and force a lookup
|
|
933
|
+
:param app_lookup_cache: Optional cache of existing app deployments to use instead of querying the indexer
|
|
934
|
+
:param approval_source_map: Optional source map for the approval program
|
|
935
|
+
:param clear_source_map: Optional source map for the clear state program
|
|
936
|
+
:return: An AppClient instance configured for the resolved application
|
|
937
|
+
|
|
938
|
+
:example:
|
|
939
|
+
>>> app_client = factory.get_app_client_by_creator_and_name(
|
|
940
|
+
... creator_address='SENDER_ADDRESS',
|
|
941
|
+
... app_name='my_app'
|
|
942
|
+
... )
|
|
943
|
+
"""
|
|
677
944
|
return AppClient.from_creator_and_name(
|
|
678
945
|
creator_address=creator_address,
|
|
679
946
|
app_name=app_name or self._app_name,
|
|
@@ -699,10 +966,23 @@ class AppFactory:
|
|
|
699
966
|
)
|
|
700
967
|
|
|
701
968
|
def import_source_maps(self, source_maps: AppSourceMaps) -> None:
|
|
969
|
+
"""
|
|
970
|
+
Import the provided source maps into the factory.
|
|
971
|
+
|
|
972
|
+
:param source_maps: An AppSourceMaps instance containing the approval and clear source maps.
|
|
973
|
+
"""
|
|
702
974
|
self._approval_source_map = source_maps.approval_source_map
|
|
703
975
|
self._clear_source_map = source_maps.clear_source_map
|
|
704
976
|
|
|
705
977
|
def compile(self, compilation_params: AppClientCompilationParams | None = None) -> AppClientCompilationResult:
|
|
978
|
+
"""Compile the app's TEAL code.
|
|
979
|
+
|
|
980
|
+
:param compilation_params: The compilation parameters
|
|
981
|
+
:return AppClientCompilationResult: The compilation result
|
|
982
|
+
|
|
983
|
+
:example:
|
|
984
|
+
>>> compilation_result = factory.compile()
|
|
985
|
+
"""
|
|
706
986
|
compilation = compilation_params or AppClientCompilationParams()
|
|
707
987
|
result = AppClient.compile(
|
|
708
988
|
app_spec=self._app_spec,
|
|
@@ -718,6 +998,13 @@ class AppFactory:
|
|
|
718
998
|
return result
|
|
719
999
|
|
|
720
1000
|
def _expose_logic_error(self, e: Exception, is_clear_state_program: bool = False) -> Exception: # noqa: FBT002 FBT001
|
|
1001
|
+
"""
|
|
1002
|
+
Convert a low-level exception into a descriptive logic error.
|
|
1003
|
+
|
|
1004
|
+
:param e: The original exception.
|
|
1005
|
+
:param is_clear_state_program: Flag indicating if the error is related to the clear state program.
|
|
1006
|
+
:return: The transformed exception.
|
|
1007
|
+
"""
|
|
721
1008
|
return AppClient._expose_logic_error_static(
|
|
722
1009
|
e=e,
|
|
723
1010
|
app_spec=self._app_spec,
|
|
@@ -730,6 +1017,12 @@ class AppFactory:
|
|
|
730
1017
|
)
|
|
731
1018
|
|
|
732
1019
|
def _get_deploy_time_control(self, control: str) -> bool | None:
|
|
1020
|
+
"""
|
|
1021
|
+
Determine the deploy time control flag for the specified control type.
|
|
1022
|
+
|
|
1023
|
+
:param control: The control type ('updatable' or 'deletable').
|
|
1024
|
+
:return: A boolean flag or None if not determinable.
|
|
1025
|
+
"""
|
|
733
1026
|
approval = self._app_spec.source.get_decoded_approval() if self._app_spec.source else None
|
|
734
1027
|
|
|
735
1028
|
template_name = UPDATABLE_TEMPLATE_NAME if control == "updatable" else DELETABLE_TEMPLATE_NAME
|
|
@@ -742,6 +1035,13 @@ class AppFactory:
|
|
|
742
1035
|
)
|
|
743
1036
|
|
|
744
1037
|
def _get_sender(self, sender: str | None) -> str:
|
|
1038
|
+
"""
|
|
1039
|
+
Retrieve the sender address.
|
|
1040
|
+
|
|
1041
|
+
:param sender: The specified sender address.
|
|
1042
|
+
:return: The sender address.
|
|
1043
|
+
:raises Exception: If no sender is provided and no default sender is set.
|
|
1044
|
+
"""
|
|
745
1045
|
if not sender and not self._default_sender:
|
|
746
1046
|
raise Exception(
|
|
747
1047
|
f"No sender provided and no default sender present in app client for call to app {self._app_name}"
|
|
@@ -749,6 +1049,13 @@ class AppFactory:
|
|
|
749
1049
|
return str(sender or self._default_sender)
|
|
750
1050
|
|
|
751
1051
|
def _get_signer(self, sender: str | None, signer: TransactionSigner | None) -> TransactionSigner | None:
|
|
1052
|
+
"""
|
|
1053
|
+
Retrieve the transaction signer.
|
|
1054
|
+
|
|
1055
|
+
:param sender: The sender address.
|
|
1056
|
+
:param signer: The provided signer.
|
|
1057
|
+
:return: The transaction signer if available.
|
|
1058
|
+
"""
|
|
752
1059
|
return signer or (self._default_signer if not sender or sender == self._default_sender else None)
|
|
753
1060
|
|
|
754
1061
|
def _handle_call_errors(self, call: Callable[[], T]) -> T:
|
|
@@ -764,6 +1071,13 @@ class AppFactory:
|
|
|
764
1071
|
],
|
|
765
1072
|
method: Method,
|
|
766
1073
|
) -> AppFactoryCreateMethodCallResult[Arc56ReturnValueType]:
|
|
1074
|
+
"""
|
|
1075
|
+
Parse the method call return value and convert the ABI return.
|
|
1076
|
+
|
|
1077
|
+
:param result: A callable that returns the transaction result.
|
|
1078
|
+
:param method: The ABI method associated with the call.
|
|
1079
|
+
:return: An AppFactoryCreateMethodCallResult with the parsed ABI return.
|
|
1080
|
+
"""
|
|
767
1081
|
result_value = result()
|
|
768
1082
|
return AppFactoryCreateMethodCallResult[Arc56ReturnValueType](
|
|
769
1083
|
**{
|