Skip to content

Commit 3af564c

Browse files
committed
chore: refining AppFactory and AppDeployer implementations
1 parent f56deac commit 3af564c

File tree

8 files changed

+184
-146
lines changed

8 files changed

+184
-146
lines changed

src/algokit_utils/applications/app_deployer.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -80,37 +80,37 @@ class AppLookup:
8080
class OnSchemaBreak(str, Enum):
8181
"""Action to take if an Application's schema has breaking changes"""
8282

83-
FAIL = "fail"
83+
Fail = "fail"
8484
"""Fail the deployment"""
85-
REPLACE_APP = "replace_app"
85+
ReplaceApp = "replace_app"
8686
"""Create a new Application and delete the old Application in a single transaction"""
87-
APPEND_APP = "append_app"
87+
AppendApp = "append_app"
8888
"""Create a new Application"""
8989

9090

9191
class OnUpdate(str, Enum):
9292
"""Action to take if an Application has been updated"""
9393

94-
FAIL = "fail"
94+
Fail = "fail"
9595
"""Fail the deployment"""
96-
UPDATE_APP = "update_app"
96+
UpdateApp = "update_app"
9797
"""Update the Application with the new approval and clear programs"""
98-
REPLACE_APP = "replace_app"
98+
ReplaceApp = "replace_app"
9999
"""Create a new Application and delete the old Application in a single transaction"""
100-
APPEND_APP = "append_app"
100+
AppendApp = "append_app"
101101
"""Create a new application"""
102102

103103

104104
class OperationPerformed(str, Enum):
105105
"""Describes the actions taken during deployment"""
106106

107-
NOTHING = "nothing"
107+
Nothing = "nothing"
108108
"""An existing Application was found"""
109-
CREATE = "create"
109+
Create = "create"
110110
"""No existing Application was found, created a new Application"""
111-
UPDATE = "update"
111+
Update = "update"
112112
"""An existing Application was found, but was out of date, updated to latest version"""
113-
REPLACE = "replace"
113+
Replace = "replace"
114114
"""An existing Application was found, but was out of date, created a new Application and deleted the original"""
115115

116116

@@ -120,8 +120,8 @@ class AppDeployParams:
120120

121121
metadata: AppDeployMetaData
122122
deploy_time_params: TealTemplateParams | None = None
123-
on_schema_break: Literal["replace", "fail", "append"] | OnSchemaBreak = OnSchemaBreak.FAIL
124-
on_update: Literal["update", "replace", "fail", "append"] | OnUpdate = OnUpdate.FAIL
123+
on_schema_break: Literal["replace", "fail", "append"] | OnSchemaBreak = OnSchemaBreak.Fail
124+
on_update: Literal["update", "replace", "fail", "append"] | OnUpdate = OnUpdate.Fail
125125
create_params: AppCreateParams | AppCreateMethodCallParams
126126
update_params: AppUpdateParams | AppUpdateMethodCallParams
127127
delete_params: AppDeleteParams | AppDeleteMethodCallParams
@@ -289,7 +289,7 @@ def deploy(self, deployment: AppDeployParams) -> AppDeployResponse:
289289
logger.debug("No detected changes in app, nothing to do.", suppress_log=deployment.suppress_log)
290290
return AppDeployResponse(
291291
app=existing_app,
292-
operation_performed=OperationPerformed.NOTHING,
292+
operation_performed=OperationPerformed.Nothing,
293293
)
294294

295295
def _create_app(
@@ -339,7 +339,7 @@ def _create_app(
339339

340340
return AppDeployResponse(
341341
app=app_metadata,
342-
operation_performed=OperationPerformed.CREATE,
342+
operation_performed=OperationPerformed.Create,
343343
create_response=create_response,
344344
)
345345

@@ -413,7 +413,7 @@ def _replace_app(
413413

414414
return AppDeployResponse(
415415
app=app_metadata,
416-
operation_performed=OperationPerformed.REPLACE,
416+
operation_performed=OperationPerformed.Replace,
417417
create_response=create_response,
418418
update_response=None,
419419
delete_response=delete_response,
@@ -465,7 +465,7 @@ def _update_app(
465465

466466
return AppDeployResponse(
467467
app=app_metadata,
468-
operation_performed=OperationPerformed.UPDATE,
468+
operation_performed=OperationPerformed.Update,
469469
update_response=result,
470470
)
471471

@@ -476,14 +476,14 @@ def _handle_schema_break(
476476
approval_program: bytes,
477477
clear_program: bytes,
478478
) -> AppDeployResponse:
479-
if deployment.on_schema_break in (OnSchemaBreak.FAIL, "fail"):
479+
if deployment.on_schema_break in (OnSchemaBreak.Fail, "fail"):
480480
raise ValueError(
481481
"Schema break detected and onSchemaBreak=OnSchemaBreak.Fail, stopping deployment. "
482482
"If you want to try deleting and recreating the app then "
483483
"re-run with onSchemaBreak=OnSchemaBreak.ReplaceApp"
484484
)
485485

486-
if deployment.on_schema_break in (OnSchemaBreak.APPEND_APP, "append"):
486+
if deployment.on_schema_break in (OnSchemaBreak.AppendApp, "append"):
487487
return self._create_app(deployment, approval_program, clear_program)
488488

489489
if existing_app.deletable:
@@ -498,21 +498,21 @@ def _handle_update(
498498
approval_program: bytes,
499499
clear_program: bytes,
500500
) -> AppDeployResponse:
501-
if deployment.on_update in (OnUpdate.FAIL, "fail"):
501+
if deployment.on_update in (OnUpdate.Fail, "fail"):
502502
raise ValueError(
503503
"Update detected and onUpdate=Fail, stopping deployment. " "Try a different onUpdate value to not fail."
504504
)
505505

506-
if deployment.on_update in (OnUpdate.APPEND_APP, "append"):
506+
if deployment.on_update in (OnUpdate.AppendApp, "append"):
507507
return self._create_app(deployment, approval_program, clear_program)
508508

509-
if deployment.on_update in (OnUpdate.UPDATE_APP, "update"):
509+
if deployment.on_update in (OnUpdate.UpdateApp, "update"):
510510
if existing_app.updatable:
511511
return self._update_app(deployment, existing_app, approval_program, clear_program)
512512
else:
513513
raise ValueError("App is not updatable but onUpdate=UpdateApp, cannot update app")
514514

515-
if deployment.on_update in (OnUpdate.REPLACE_APP, "replace"):
515+
if deployment.on_update in (OnUpdate.ReplaceApp, "replace"):
516516
if existing_app.deletable:
517517
return self._replace_app(deployment, existing_app, approval_program, clear_program)
518518
else:

src/algokit_utils/applications/app_factory.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@
4848
from algokit_utils.models.state import TealTemplateParams
4949
from algokit_utils.models.transaction import (
5050
SendAppCreateTransactionResult,
51+
SendAppCreateTransactionResultBase,
5152
SendAppTransactionResult,
53+
SendAppTransactionResultBase,
5254
SendAppUpdateTransactionResult,
55+
SendAppUpdateTransactionResultBase,
5356
SendParams,
5457
SendSingleTransactionResult,
55-
_SendAppCreateTransactionResult,
56-
_SendAppTransactionResult,
57-
_SendAppUpdateTransactionResult,
5858
)
5959
from algokit_utils.protocols.application import AlgorandClientProtocol
6060
from algokit_utils.transactions.transaction_composer import (
@@ -117,7 +117,7 @@ class AppFactoryCreateMethodCallWithSendParams(AppFactoryCreateMethodCallParams,
117117

118118

119119
@dataclass(frozen=True)
120-
class SendAppTransactionResultWithABIValue(_SendAppTransactionResult[ABIValue | ABIStruct | None]):
120+
class SendAppTransactionResultWithABIValue(SendAppTransactionResultBase[ABIValue | ABIStruct | None]):
121121
@classmethod
122122
def from_send_app_txn(
123123
cls, response: SendAppTransactionResult | None, abi_return: ABIValue | ABIStruct | None
@@ -131,7 +131,7 @@ def from_send_app_txn(
131131

132132

133133
@dataclass(frozen=True)
134-
class SendAppUpdateTransactionResultWithABIValue(_SendAppUpdateTransactionResult[ABIValue | ABIStruct | None]):
134+
class SendAppUpdateTransactionResultWithABIValue(SendAppUpdateTransactionResultBase[ABIValue | ABIStruct | None]):
135135
@classmethod
136136
def from_send_app_update_txn(
137137
cls, response: SendAppUpdateTransactionResult | None, abi_return: ABIValue | ABIStruct | None
@@ -145,7 +145,7 @@ def from_send_app_update_txn(
145145

146146

147147
@dataclass(frozen=True, kw_only=True)
148-
class SendAppCreateTransactionResultWithABIValue(_SendAppCreateTransactionResult[ABIValue | ABIStruct | None]):
148+
class SendAppCreateTransactionResultWithABIValue(SendAppCreateTransactionResultBase[ABIValue | ABIStruct | None]):
149149
@classmethod
150150
def from_send_app_create_txn(
151151
cls, response: SendAppCreateTransactionResult | None, abi_return: ABIValue | ABIStruct | None
@@ -180,10 +180,12 @@ def from_deploy_response(
180180
def set_compilation_data(response: Any, compilation_data: AppClientCompilationResult | None) -> Any: # noqa: ANN401
181181
if compilation_data is None:
182182
return response
183-
if hasattr(response, "compiled_approval"):
184-
response.compiled_approval = compilation_data.compiled_approval
185-
if hasattr(response, "compiled_clear"):
186-
response.compiled_clear = compilation_data.compiled_clear
183+
if hasattr(response, "compiled_approval") and hasattr(compilation_data, "compiled_approval"):
184+
return replace(
185+
response,
186+
compiled_approval=compilation_data.compiled_approval,
187+
compiled_clear=compilation_data.compiled_clear,
188+
)
187189
return response
188190

189191
def process_abi_response(
@@ -198,7 +200,7 @@ def process_abi_response(
198200
return None
199201

200202
abi_return = None
201-
if isinstance(params, AppClientMethodCallParams):
203+
if response_data.abi_return and hasattr(params, "method"):
202204
abi_return = get_arc56_return_value(
203205
response_data.abi_return,
204206
get_arc56_method(params.method, app_client.app_spec),
@@ -528,8 +530,8 @@ def deploy( # noqa: PLR0913
528530
self,
529531
*,
530532
deploy_time_params: TealTemplateParams | None = None,
531-
on_update: OnUpdate = OnUpdate.FAIL,
532-
on_schema_break: OnSchemaBreak = OnSchemaBreak.FAIL,
533+
on_update: OnUpdate = OnUpdate.Fail,
534+
on_schema_break: OnSchemaBreak = OnSchemaBreak.Fail,
533535
create_params: AppClientMethodCallParams | AppClientBareCallParams | None = None,
534536
update_params: AppClientMethodCallParams | AppClientBareCallParams | None = None,
535537
delete_params: AppClientMethodCallParams | AppClientBareCallParams | None = None,

src/algokit_utils/applications/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
T = TypeVar("T", bound=ABIValue | bytes | ABIStruct | None)
3434

3535

36-
def get_arc56_method(method_name_or_signature: str, app_spec: Arc56Contract) -> Arc56Method:
36+
def get_arc56_method(method_name_or_signature: str | Arc56Method, app_spec: Arc56Contract) -> Arc56Method:
37+
if isinstance(method_name_or_signature, Arc56Method):
38+
return method_name_or_signature
39+
3740
if "(" not in method_name_or_signature:
3841
# Filter by method name
3942
methods = [m for m in app_spec.methods if m.name == method_name_or_signature]

src/algokit_utils/models/transaction.py

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -125,77 +125,80 @@ class SendSingleTransactionResult:
125125
def from_composer_result(cls, result: SendAtomicTransactionComposerResults, index: int = -1) -> Self:
126126
# Get base parameters
127127
base_params = {
128-
"transaction": TransactionWrapper(result.transactions[index]),
128+
"transaction": result.transactions[index],
129129
"confirmation": result.confirmations[index],
130130
"group_id": result.group_id,
131131
"tx_id": result.tx_ids[index],
132132
"tx_ids": result.tx_ids,
133-
"transactions": result.transactions,
133+
"transactions": [result.transactions[index]],
134134
"confirmations": result.confirmations,
135135
"returns": result.returns,
136136
}
137137

138138
# For asset creation, extract asset_id from confirmation
139139
if cls is SendSingleAssetCreateTransactionResult:
140-
base_params["asset_id"] = result.confirmations[index]["asset-index"] # type: ignore[index]
140+
base_params["asset_id"] = result.confirmations[index]["asset-index"] # type: ignore[call-overload]
141141
# For app creation, extract app_id and calculate app_address
142142
elif cls is SendAppCreateTransactionResult:
143-
app_id = result.confirmations[index]["application-index"] # type: ignore[index]
143+
app_id = result.confirmations[index]["application-index"] # type: ignore[call-overload]
144144
base_params.update(
145145
{
146146
"app_id": app_id,
147147
"app_address": algosdk.logic.get_application_address(app_id),
148-
"abi_return": result.returns[index] if result.returns else None,
149-
"compiled_approval": None, # These would need to be passed in separately
150-
"compiled_clear": None, # if needed
148+
"abi_return": result.returns[index] if result.returns else None, # type: ignore[dict-item]
151149
}
152150
)
153151
# For regular app transactions, just add abi_return
154152
elif cls is SendAppTransactionResult:
155-
base_params["abi_return"] = result.returns[index] if result.returns else None
153+
base_params["abi_return"] = result.returns[index] if result.returns else None # type: ignore[assignment]
156154

157-
return cls(**base_params)
155+
return cls(**base_params) # type: ignore[arg-type]
158156

159157

160158
@dataclass(frozen=True, kw_only=True)
161159
class SendSingleAssetCreateTransactionResult(SendSingleTransactionResult):
162160
asset_id: int
163161

164162

165-
T = TypeVar("T")
163+
ABIReturnT = TypeVar("ABIReturnT")
166164

167165

168166
@dataclass(frozen=True)
169-
class _SendAppTransactionResult(Generic[T], SendSingleTransactionResult):
170-
abi_return: T | None = None
171-
167+
class SendAppTransactionResultBase(SendSingleTransactionResult, Generic[ABIReturnT]):
168+
"""Base class for all app transaction results with generic ABI return type"""
172169

173-
@dataclass(frozen=True)
174-
class SendAppTransactionResult(_SendAppTransactionResult[ABIReturn]):
175-
pass
170+
abi_return: ABIReturnT | None = None
176171

177172

178173
@dataclass(frozen=True)
179-
class _SendAppUpdateTransactionResult(Generic[T], SendSingleTransactionResult):
180-
abi_return: T | None = None
174+
class SendAppUpdateTransactionResultBase(SendAppTransactionResultBase[ABIReturnT]):
175+
"""Base class for app update transaction results"""
176+
181177
compiled_approval: Any | None = None
182178
compiled_clear: Any | None = None
183179

184180

185-
@dataclass(frozen=True)
186-
class SendAppUpdateTransactionResult(_SendAppUpdateTransactionResult[ABIReturn]):
187-
pass
188-
181+
@dataclass(frozen=True, kw_only=True)
182+
class SendAppCreateTransactionResultBase(SendAppTransactionResultBase[ABIReturnT]):
183+
"""Base class for app create transaction results"""
189184

190-
@dataclass(frozen=True)
191-
class _SendAppCreateTransactionResult(Generic[T], SendSingleTransactionResult):
192185
app_id: int
193186
app_address: str
194-
abi_return: T | None = None
195187
compiled_approval: Any | None = None
196188
compiled_clear: Any | None = None
197189

198190

191+
# Concrete implementations with ABIReturn type
192+
@dataclass(frozen=True)
193+
class SendAppTransactionResult(SendAppTransactionResultBase[ABIReturn]):
194+
"""Standard app transaction result with ABIReturn type"""
195+
196+
197+
@dataclass(frozen=True)
198+
class SendAppUpdateTransactionResult(SendAppUpdateTransactionResultBase[ABIReturn]):
199+
"""Standard app update transaction result with ABIReturn type"""
200+
201+
199202
@dataclass(frozen=True, kw_only=True)
200-
class SendAppCreateTransactionResult(_SendAppCreateTransactionResult):
201-
pass
203+
class SendAppCreateTransactionResult(SendAppCreateTransactionResultBase[ABIReturn]):
204+
"""Standard app create transaction result with ABIReturn type"""

src/algokit_utils/protocols/application.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919

2020
@dataclass
21-
class NetworkDetails:
21+
class _NetworkDetails:
2222
genesis_id: str
2323
genesis_hash: str
2424
network_name: str
@@ -52,7 +52,7 @@ def algod(self) -> AlgodClient: ...
5252
@property
5353
def indexer(self) -> IndexerClient | None: ...
5454

55-
async def network(self) -> NetworkDetails: ...
55+
async def network(self) -> _NetworkDetails: ...
5656

5757
async def is_local_net(self) -> bool: ...
5858

src/algokit_utils/transactions/transaction_composer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from algokit_utils._debugging import simulate_and_persist_response, simulate_response
2020
from algokit_utils.applications.app_manager import AppManager
2121
from algokit_utils.config import config
22-
from algokit_utils.models.state import BoxIdentifier
2322
from algokit_utils.models.transaction import SendAtomicTransactionComposerResults, SendParams, TransactionWrapper
2423
from algokit_utils.transactions.utils import encode_lease, get_abi_return_value, populate_app_call_resources
2524

@@ -32,7 +31,7 @@
3231

3332
from algokit_utils.models.abi import ABIValue
3433
from algokit_utils.models.amount import AlgoAmount
35-
from algokit_utils.models.state import BoxReference
34+
from algokit_utils.models.state import BoxIdentifier, BoxReference
3635
from algokit_utils.models.transaction import Arc2TransactionNote
3736

3837

0 commit comments

Comments
 (0)