algokit-utils 2.4.0b1__py3-none-any.whl → 3.0.0b2__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 +23 -181
- algokit_utils/_debugging.py +89 -45
- algokit_utils/_legacy_v2/__init__.py +177 -0
- algokit_utils/{_ensure_funded.py → _legacy_v2/_ensure_funded.py} +19 -18
- algokit_utils/{_transfer.py → _legacy_v2/_transfer.py} +24 -23
- algokit_utils/_legacy_v2/account.py +203 -0
- algokit_utils/_legacy_v2/application_client.py +1471 -0
- algokit_utils/_legacy_v2/application_specification.py +21 -0
- algokit_utils/_legacy_v2/asset.py +168 -0
- algokit_utils/_legacy_v2/common.py +28 -0
- algokit_utils/_legacy_v2/deploy.py +822 -0
- algokit_utils/_legacy_v2/logic_error.py +14 -0
- algokit_utils/{models.py → _legacy_v2/models.py} +16 -45
- algokit_utils/_legacy_v2/network_clients.py +140 -0
- algokit_utils/account.py +12 -183
- algokit_utils/accounts/__init__.py +2 -0
- algokit_utils/accounts/account_manager.py +909 -0
- algokit_utils/accounts/kmd_account_manager.py +159 -0
- algokit_utils/algorand.py +265 -0
- algokit_utils/application_client.py +9 -1447
- algokit_utils/application_specification.py +39 -197
- algokit_utils/applications/__init__.py +7 -0
- algokit_utils/applications/abi.py +276 -0
- algokit_utils/applications/app_client.py +2056 -0
- algokit_utils/applications/app_deployer.py +600 -0
- algokit_utils/applications/app_factory.py +826 -0
- algokit_utils/applications/app_manager.py +470 -0
- algokit_utils/applications/app_spec/__init__.py +2 -0
- algokit_utils/applications/app_spec/arc32.py +207 -0
- algokit_utils/applications/app_spec/arc56.py +1023 -0
- algokit_utils/applications/enums.py +40 -0
- algokit_utils/asset.py +32 -168
- algokit_utils/assets/__init__.py +1 -0
- algokit_utils/assets/asset_manager.py +320 -0
- algokit_utils/beta/_utils.py +36 -0
- algokit_utils/beta/account_manager.py +4 -195
- algokit_utils/beta/algorand_client.py +4 -314
- algokit_utils/beta/client_manager.py +5 -74
- algokit_utils/beta/composer.py +5 -712
- algokit_utils/clients/__init__.py +2 -0
- algokit_utils/clients/client_manager.py +656 -0
- algokit_utils/clients/dispenser_api_client.py +192 -0
- algokit_utils/common.py +8 -26
- algokit_utils/config.py +71 -18
- algokit_utils/deploy.py +7 -894
- algokit_utils/dispenser_api.py +8 -176
- algokit_utils/errors/__init__.py +1 -0
- algokit_utils/errors/logic_error.py +121 -0
- algokit_utils/logic_error.py +7 -82
- algokit_utils/models/__init__.py +8 -0
- algokit_utils/models/account.py +193 -0
- algokit_utils/models/amount.py +198 -0
- algokit_utils/models/application.py +61 -0
- algokit_utils/models/network.py +25 -0
- algokit_utils/models/simulate.py +11 -0
- algokit_utils/models/state.py +59 -0
- algokit_utils/models/transaction.py +100 -0
- algokit_utils/network_clients.py +7 -128
- algokit_utils/protocols/__init__.py +2 -0
- algokit_utils/protocols/account.py +22 -0
- algokit_utils/protocols/typed_clients.py +108 -0
- algokit_utils/transactions/__init__.py +3 -0
- algokit_utils/transactions/transaction_composer.py +2293 -0
- algokit_utils/transactions/transaction_creator.py +156 -0
- algokit_utils/transactions/transaction_sender.py +574 -0
- {algokit_utils-2.4.0b1.dist-info → algokit_utils-3.0.0b2.dist-info}/METADATA +11 -7
- algokit_utils-3.0.0b2.dist-info/RECORD +70 -0
- {algokit_utils-2.4.0b1.dist-info → algokit_utils-3.0.0b2.dist-info}/WHEEL +1 -1
- algokit_utils-2.4.0b1.dist-info/RECORD +0 -24
- {algokit_utils-2.4.0b1.dist-info → algokit_utils-3.0.0b2.dist-info}/LICENSE +0 -0
algokit_utils/beta/composer.py
CHANGED
|
@@ -1,716 +1,9 @@
|
|
|
1
|
-
from
|
|
2
|
-
from dataclasses import dataclass
|
|
3
|
-
from typing import Union
|
|
1
|
+
from typing import Any
|
|
4
2
|
|
|
5
|
-
import
|
|
6
|
-
from algosdk.abi import Method
|
|
7
|
-
from algosdk.atomic_transaction_composer import (
|
|
8
|
-
AtomicTransactionComposer,
|
|
9
|
-
AtomicTransactionResponse,
|
|
10
|
-
TransactionSigner,
|
|
11
|
-
TransactionWithSigner,
|
|
12
|
-
)
|
|
13
|
-
from algosdk.box_reference import BoxReference
|
|
14
|
-
from algosdk.transaction import OnComplete
|
|
15
|
-
from algosdk.v2client.algod import AlgodClient
|
|
3
|
+
from algokit_utils.beta._utils import handle_getattr
|
|
16
4
|
|
|
17
5
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
sender: str
|
|
6
|
+
def __getattr__(name: str) -> Any: # noqa: ANN401
|
|
7
|
+
"""Handle deprecated imports of parameter classes"""
|
|
21
8
|
|
|
22
|
-
|
|
23
|
-
@dataclass(frozen=True)
|
|
24
|
-
class CommonTxnParams:
|
|
25
|
-
"""
|
|
26
|
-
Common transaction parameters.
|
|
27
|
-
|
|
28
|
-
:param signer: The function used to sign transactions.
|
|
29
|
-
:param rekey_to: Change the signing key of the sender to the given address.
|
|
30
|
-
:param note: Note to attach to the transaction.
|
|
31
|
-
:param lease: Prevent multiple transactions with the same lease being included within the validity window.
|
|
32
|
-
:param static_fee: The transaction fee. In most cases you want to use `extra_fee` unless setting the fee to 0 to be covered by another transaction.
|
|
33
|
-
:param extra_fee: The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees.
|
|
34
|
-
:param max_fee: Throw an error if the fee for the transaction is more than this amount.
|
|
35
|
-
:param validity_window: How many rounds the transaction should be valid for.
|
|
36
|
-
:param first_valid_round: Set the first round this transaction is valid. If left undefined, the value from algod will be used. Only set this when you intentionally want this to be some time in the future.
|
|
37
|
-
:param last_valid_round: The last round this transaction is valid. It is recommended to use validity_window instead.
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
signer: TransactionSigner | None = None
|
|
41
|
-
rekey_to: str | None = None
|
|
42
|
-
note: bytes | None = None
|
|
43
|
-
lease: bytes | None = None
|
|
44
|
-
static_fee: int | None = None
|
|
45
|
-
extra_fee: int | None = None
|
|
46
|
-
max_fee: int | None = None
|
|
47
|
-
validity_window: int | None = None
|
|
48
|
-
first_valid_round: int | None = None
|
|
49
|
-
last_valid_round: int | None = None
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@dataclass(frozen=True)
|
|
53
|
-
class _RequiredPayTxnParams(SenderParam):
|
|
54
|
-
receiver: str
|
|
55
|
-
amount: int
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@dataclass(frozen=True)
|
|
59
|
-
class PayParams(CommonTxnParams, _RequiredPayTxnParams):
|
|
60
|
-
"""
|
|
61
|
-
Payment transaction parameters.
|
|
62
|
-
|
|
63
|
-
:param receiver: The account that will receive the ALGO.
|
|
64
|
-
:param amount: Amount to send.
|
|
65
|
-
:param close_remainder_to: If given, close the sender account and send the remaining balance to this address.
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
close_remainder_to: str | None = None
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@dataclass(frozen=True)
|
|
72
|
-
class _RequiredAssetCreateParams(SenderParam):
|
|
73
|
-
total: int
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
@dataclass(frozen=True)
|
|
77
|
-
class AssetCreateParams(CommonTxnParams, _RequiredAssetCreateParams):
|
|
78
|
-
"""
|
|
79
|
-
Asset creation parameters.
|
|
80
|
-
|
|
81
|
-
:param total: The total amount of the smallest divisible unit to create.
|
|
82
|
-
:param decimals: The amount of decimal places the asset should have.
|
|
83
|
-
:param default_frozen: Whether the asset is frozen by default in the creator address.
|
|
84
|
-
:param manager: The address that can change the manager, reserve, clawback, and freeze addresses. There will permanently be no manager if undefined or an empty string.
|
|
85
|
-
:param reserve: The address that holds the uncirculated supply.
|
|
86
|
-
:param freeze: The address that can freeze the asset in any account. Freezing will be permanently disabled if undefined or an empty string.
|
|
87
|
-
:param clawback: The address that can clawback the asset from any account. Clawback will be permanently disabled if undefined or an empty string.
|
|
88
|
-
:param unit_name: The short ticker name for the asset.
|
|
89
|
-
:param asset_name: The full name of the asset.
|
|
90
|
-
:param url: The metadata URL for the asset.
|
|
91
|
-
:param metadata_hash: Hash of the metadata contained in the metadata URL.
|
|
92
|
-
"""
|
|
93
|
-
|
|
94
|
-
decimals: int | None = None
|
|
95
|
-
default_frozen: bool | None = None
|
|
96
|
-
manager: str | None = None
|
|
97
|
-
reserve: str | None = None
|
|
98
|
-
freeze: str | None = None
|
|
99
|
-
clawback: str | None = None
|
|
100
|
-
unit_name: str | None = None
|
|
101
|
-
asset_name: str | None = None
|
|
102
|
-
url: str | None = None
|
|
103
|
-
metadata_hash: bytes | None = None
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@dataclass(frozen=True)
|
|
107
|
-
class _RequiredAssetConfigParams(SenderParam):
|
|
108
|
-
asset_id: int
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
@dataclass(frozen=True)
|
|
112
|
-
class AssetConfigParams(CommonTxnParams, _RequiredAssetConfigParams):
|
|
113
|
-
"""
|
|
114
|
-
Asset configuration parameters.
|
|
115
|
-
|
|
116
|
-
:param asset_id: ID of the asset.
|
|
117
|
-
:param manager: The address that can change the manager, reserve, clawback, and freeze addresses. There will permanently be no manager if undefined or an empty string.
|
|
118
|
-
:param reserve: The address that holds the uncirculated supply.
|
|
119
|
-
:param freeze: The address that can freeze the asset in any account. Freezing will be permanently disabled if undefined or an empty string.
|
|
120
|
-
:param clawback: The address that can clawback the asset from any account. Clawback will be permanently disabled if undefined or an empty string.
|
|
121
|
-
"""
|
|
122
|
-
|
|
123
|
-
manager: str | None = None
|
|
124
|
-
reserve: str | None = None
|
|
125
|
-
freeze: str | None = None
|
|
126
|
-
clawback: str | None = None
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@dataclass(frozen=True)
|
|
130
|
-
class _RequiredAssetFreezeParams(SenderParam):
|
|
131
|
-
asset_id: int
|
|
132
|
-
account: str
|
|
133
|
-
frozen: bool
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@dataclass(frozen=True)
|
|
137
|
-
class AssetFreezeParams(CommonTxnParams, _RequiredAssetFreezeParams):
|
|
138
|
-
"""
|
|
139
|
-
Asset freeze parameters.
|
|
140
|
-
|
|
141
|
-
:param asset_id: The ID of the asset.
|
|
142
|
-
:param account: The account to freeze or unfreeze.
|
|
143
|
-
:param frozen: Whether the assets in the account should be frozen.
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@dataclass(frozen=True)
|
|
148
|
-
class _RequiredAssetDestroyParams(SenderParam):
|
|
149
|
-
asset_id: int
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@dataclass(frozen=True)
|
|
153
|
-
class AssetDestroyParams(CommonTxnParams, _RequiredAssetDestroyParams):
|
|
154
|
-
"""
|
|
155
|
-
Asset destruction parameters.
|
|
156
|
-
|
|
157
|
-
:param asset_id: ID of the asset.
|
|
158
|
-
"""
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@dataclass(frozen=True)
|
|
162
|
-
class _RequiredOnlineKeyRegParams(SenderParam):
|
|
163
|
-
vote_key: str
|
|
164
|
-
selection_key: str
|
|
165
|
-
vote_first: int
|
|
166
|
-
vote_last: int
|
|
167
|
-
vote_key_dilution: int
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
@dataclass(frozen=True)
|
|
171
|
-
class OnlineKeyRegParams(CommonTxnParams, _RequiredOnlineKeyRegParams):
|
|
172
|
-
"""
|
|
173
|
-
Online key registration parameters.
|
|
174
|
-
|
|
175
|
-
:param vote_key: The root participation public key.
|
|
176
|
-
:param selection_key: The VRF public key.
|
|
177
|
-
:param vote_first: The first round that the participation key is valid. Not to be confused with the `first_valid` round of the keyreg transaction.
|
|
178
|
-
:param vote_last: The last round that the participation key is valid. Not to be confused with the `last_valid` round of the keyreg transaction.
|
|
179
|
-
:param vote_key_dilution: This is the dilution for the 2-level participation key. It determines the interval (number of rounds) for generating new ephemeral keys.
|
|
180
|
-
:param state_proof_key: The 64 byte state proof public key commitment.
|
|
181
|
-
"""
|
|
182
|
-
|
|
183
|
-
state_proof_key: bytes | None = None
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
@dataclass(frozen=True)
|
|
187
|
-
class _RequiredAssetTransferParams(SenderParam):
|
|
188
|
-
asset_id: int
|
|
189
|
-
amount: int
|
|
190
|
-
receiver: str
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
@dataclass(frozen=True)
|
|
194
|
-
class AssetTransferParams(CommonTxnParams, _RequiredAssetTransferParams):
|
|
195
|
-
"""
|
|
196
|
-
Asset transfer parameters.
|
|
197
|
-
|
|
198
|
-
:param asset_id: ID of the asset.
|
|
199
|
-
:param amount: Amount of the asset to transfer (smallest divisible unit).
|
|
200
|
-
:param receiver: The account to send the asset to.
|
|
201
|
-
:param clawback_target: The account to take the asset from.
|
|
202
|
-
:param close_asset_to: The account to close the asset to.
|
|
203
|
-
"""
|
|
204
|
-
|
|
205
|
-
clawback_target: str | None = None
|
|
206
|
-
close_asset_to: str | None = None
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
@dataclass(frozen=True)
|
|
210
|
-
class _RequiredAssetOptInParams(SenderParam):
|
|
211
|
-
asset_id: int
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
@dataclass(frozen=True)
|
|
215
|
-
class AssetOptInParams(CommonTxnParams, _RequiredAssetOptInParams):
|
|
216
|
-
"""
|
|
217
|
-
Asset opt-in parameters.
|
|
218
|
-
|
|
219
|
-
:param asset_id: ID of the asset.
|
|
220
|
-
"""
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
@dataclass(frozen=True)
|
|
224
|
-
class AppCallParams(CommonTxnParams, SenderParam):
|
|
225
|
-
"""
|
|
226
|
-
Application call parameters.
|
|
227
|
-
|
|
228
|
-
:param on_complete: The OnComplete action.
|
|
229
|
-
:param app_id: ID of the application.
|
|
230
|
-
:param approval_program: The program to execute for all OnCompletes other than ClearState.
|
|
231
|
-
:param clear_program: The program to execute for ClearState OnComplete.
|
|
232
|
-
:param schema: The state schema for the app. This is immutable.
|
|
233
|
-
:param args: Application arguments.
|
|
234
|
-
:param account_references: Account references.
|
|
235
|
-
:param app_references: App references.
|
|
236
|
-
:param asset_references: Asset references.
|
|
237
|
-
:param extra_pages: Number of extra pages required for the programs.
|
|
238
|
-
:param box_references: Box references.
|
|
239
|
-
"""
|
|
240
|
-
|
|
241
|
-
on_complete: OnComplete | None = None
|
|
242
|
-
app_id: int | None = None
|
|
243
|
-
approval_program: bytes | None = None
|
|
244
|
-
clear_program: bytes | None = None
|
|
245
|
-
schema: dict[str, int] | None = None
|
|
246
|
-
args: list[bytes] | None = None
|
|
247
|
-
account_references: list[str] | None = None
|
|
248
|
-
app_references: list[int] | None = None
|
|
249
|
-
asset_references: list[int] | None = None
|
|
250
|
-
extra_pages: int | None = None
|
|
251
|
-
box_references: list[BoxReference] | None = None
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
@dataclass(frozen=True)
|
|
255
|
-
class _RequiredMethodCallParams(SenderParam):
|
|
256
|
-
app_id: int
|
|
257
|
-
method: Method
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
@dataclass(frozen=True)
|
|
261
|
-
class MethodCallParams(CommonTxnParams, _RequiredMethodCallParams):
|
|
262
|
-
"""
|
|
263
|
-
Method call parameters.
|
|
264
|
-
|
|
265
|
-
:param app_id: ID of the application.
|
|
266
|
-
:param method: The ABI method to call.
|
|
267
|
-
:param args: Arguments to the ABI method.
|
|
268
|
-
"""
|
|
269
|
-
|
|
270
|
-
args: list | None = None
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
TxnParams = Union[ # noqa: UP007
|
|
274
|
-
PayParams,
|
|
275
|
-
AssetCreateParams,
|
|
276
|
-
AssetConfigParams,
|
|
277
|
-
AssetFreezeParams,
|
|
278
|
-
AssetDestroyParams,
|
|
279
|
-
OnlineKeyRegParams,
|
|
280
|
-
AssetTransferParams,
|
|
281
|
-
AssetOptInParams,
|
|
282
|
-
AppCallParams,
|
|
283
|
-
MethodCallParams,
|
|
284
|
-
]
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
class AlgokitComposer:
|
|
288
|
-
"""
|
|
289
|
-
A class for composing and managing Algorand transactions using the Algosdk library.
|
|
290
|
-
|
|
291
|
-
Attributes:
|
|
292
|
-
txn_method_map (dict[str, algosdk.abi.Method]): A dictionary that maps transaction IDs to their corresponding ABI methods.
|
|
293
|
-
txns (List[Union[TransactionWithSigner, TxnParams, AtomicTransactionComposer]]): A list of transactions that have not yet been composed.
|
|
294
|
-
atc (AtomicTransactionComposer): An instance of AtomicTransactionComposer used to compose transactions.
|
|
295
|
-
algod (AlgodClient): The AlgodClient instance used by the composer for suggested params.
|
|
296
|
-
get_suggested_params (Callable[[], algosdk.future.transaction.SuggestedParams]): A function that returns suggested parameters for transactions.
|
|
297
|
-
get_signer (Callable[[str], TransactionSigner]): A function that takes an address as input and returns a TransactionSigner for that address.
|
|
298
|
-
default_validity_window (int): The default validity window for transactions.
|
|
299
|
-
"""
|
|
300
|
-
|
|
301
|
-
def __init__(
|
|
302
|
-
self,
|
|
303
|
-
algod: AlgodClient,
|
|
304
|
-
get_signer: Callable[[str], TransactionSigner],
|
|
305
|
-
get_suggested_params: Callable[[], algosdk.transaction.SuggestedParams] | None = None,
|
|
306
|
-
default_validity_window: int | None = None,
|
|
307
|
-
):
|
|
308
|
-
"""
|
|
309
|
-
Initialize an instance of the AlgokitComposer class.
|
|
310
|
-
|
|
311
|
-
Args:
|
|
312
|
-
algod (AlgodClient): An instance of AlgodClient used to get suggested params and send transactions.
|
|
313
|
-
get_signer (Callable[[str], TransactionSigner]): A function that takes an address as input and returns a TransactionSigner for that address.
|
|
314
|
-
get_suggested_params (Optional[Callable[[], algosdk.future.transaction.SuggestedParams]], optional): A function that returns suggested parameters for transactions. If not provided, it defaults to using algod.suggested_params(). Defaults to None.
|
|
315
|
-
default_validity_window (Optional[int], optional): The default validity window for transactions. If not provided, it defaults to 10. Defaults to None.
|
|
316
|
-
"""
|
|
317
|
-
self.txn_method_map: dict[str, algosdk.abi.Method] = {}
|
|
318
|
-
self.txns: list[TransactionWithSigner | TxnParams | AtomicTransactionComposer] = []
|
|
319
|
-
self.atc: AtomicTransactionComposer = AtomicTransactionComposer()
|
|
320
|
-
self.algod: AlgodClient = algod
|
|
321
|
-
self.default_get_send_params = lambda: self.algod.suggested_params()
|
|
322
|
-
self.get_suggested_params = get_suggested_params or self.default_get_send_params
|
|
323
|
-
self.get_signer: Callable[[str], TransactionSigner] = get_signer
|
|
324
|
-
self.default_validity_window: int = default_validity_window or 10
|
|
325
|
-
|
|
326
|
-
def add_payment(self, params: PayParams) -> "AlgokitComposer":
|
|
327
|
-
self.txns.append(params)
|
|
328
|
-
return self
|
|
329
|
-
|
|
330
|
-
def add_asset_create(self, params: AssetCreateParams) -> "AlgokitComposer":
|
|
331
|
-
self.txns.append(params)
|
|
332
|
-
return self
|
|
333
|
-
|
|
334
|
-
def add_asset_config(self, params: AssetConfigParams) -> "AlgokitComposer":
|
|
335
|
-
self.txns.append(params)
|
|
336
|
-
return self
|
|
337
|
-
|
|
338
|
-
def add_asset_freeze(self, params: AssetFreezeParams) -> "AlgokitComposer":
|
|
339
|
-
self.txns.append(params)
|
|
340
|
-
return self
|
|
341
|
-
|
|
342
|
-
def add_asset_destroy(self, params: AssetDestroyParams) -> "AlgokitComposer":
|
|
343
|
-
self.txns.append(params)
|
|
344
|
-
return self
|
|
345
|
-
|
|
346
|
-
def add_asset_transfer(self, params: AssetTransferParams) -> "AlgokitComposer":
|
|
347
|
-
self.txns.append(params)
|
|
348
|
-
return self
|
|
349
|
-
|
|
350
|
-
def add_asset_opt_in(self, params: AssetOptInParams) -> "AlgokitComposer":
|
|
351
|
-
self.txns.append(params)
|
|
352
|
-
return self
|
|
353
|
-
|
|
354
|
-
def add_app_call(self, params: AppCallParams) -> "AlgokitComposer":
|
|
355
|
-
self.txns.append(params)
|
|
356
|
-
return self
|
|
357
|
-
|
|
358
|
-
def add_online_key_reg(self, params: OnlineKeyRegParams) -> "AlgokitComposer":
|
|
359
|
-
self.txns.append(params)
|
|
360
|
-
return self
|
|
361
|
-
|
|
362
|
-
def add_atc(self, atc: AtomicTransactionComposer) -> "AlgokitComposer":
|
|
363
|
-
self.txns.append(atc)
|
|
364
|
-
return self
|
|
365
|
-
|
|
366
|
-
def add_method_call(self, params: MethodCallParams) -> "AlgokitComposer":
|
|
367
|
-
self.txns.append(params)
|
|
368
|
-
return self
|
|
369
|
-
|
|
370
|
-
def _build_atc(self, atc: AtomicTransactionComposer) -> list[TransactionWithSigner]:
|
|
371
|
-
group = atc.build_group()
|
|
372
|
-
|
|
373
|
-
for ts in group:
|
|
374
|
-
ts.txn.group = None
|
|
375
|
-
|
|
376
|
-
method = atc.method_dict.get(len(group) - 1)
|
|
377
|
-
if method:
|
|
378
|
-
self.txn_method_map[group[-1].txn.get_txid()] = method # type: ignore[no-untyped-call]
|
|
379
|
-
|
|
380
|
-
return group
|
|
381
|
-
|
|
382
|
-
def _common_txn_build_step(
|
|
383
|
-
self,
|
|
384
|
-
params: CommonTxnParams,
|
|
385
|
-
txn: algosdk.transaction.Transaction,
|
|
386
|
-
suggested_params: algosdk.transaction.SuggestedParams,
|
|
387
|
-
) -> algosdk.transaction.Transaction:
|
|
388
|
-
if params.lease:
|
|
389
|
-
txn.lease = params.lease
|
|
390
|
-
if params.rekey_to:
|
|
391
|
-
txn.rekey_to = params.rekey_to
|
|
392
|
-
if params.note:
|
|
393
|
-
txn.note = params.note
|
|
394
|
-
|
|
395
|
-
if params.first_valid_round:
|
|
396
|
-
txn.first_valid_round = params.first_valid_round
|
|
397
|
-
|
|
398
|
-
if params.last_valid_round:
|
|
399
|
-
txn.last_valid_round = params.last_valid_round
|
|
400
|
-
else:
|
|
401
|
-
txn.last_valid_round = txn.first_valid_round + (params.validity_window or self.default_validity_window)
|
|
402
|
-
|
|
403
|
-
if params.static_fee is not None and params.extra_fee is not None:
|
|
404
|
-
raise ValueError("Cannot set both static_fee and extra_fee")
|
|
405
|
-
|
|
406
|
-
if params.static_fee is not None:
|
|
407
|
-
txn.fee = params.static_fee
|
|
408
|
-
else:
|
|
409
|
-
txn.fee = txn.estimate_size() * suggested_params.fee or algosdk.constants.min_txn_fee # type: ignore[no-untyped-call]
|
|
410
|
-
if params.extra_fee:
|
|
411
|
-
txn.fee += params.extra_fee
|
|
412
|
-
|
|
413
|
-
if params.max_fee is not None and txn.fee > params.max_fee:
|
|
414
|
-
raise ValueError(f"Transaction fee {txn.fee} is greater than max_fee {params.max_fee}")
|
|
415
|
-
|
|
416
|
-
return txn
|
|
417
|
-
|
|
418
|
-
def _build_payment(
|
|
419
|
-
self, params: PayParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
420
|
-
) -> algosdk.transaction.Transaction:
|
|
421
|
-
txn = algosdk.transaction.PaymentTxn(
|
|
422
|
-
sender=params.sender,
|
|
423
|
-
sp=suggested_params,
|
|
424
|
-
receiver=params.receiver,
|
|
425
|
-
amt=params.amount,
|
|
426
|
-
close_remainder_to=params.close_remainder_to,
|
|
427
|
-
) # type: ignore[no-untyped-call]
|
|
428
|
-
|
|
429
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
430
|
-
|
|
431
|
-
def _build_asset_create(
|
|
432
|
-
self, params: AssetCreateParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
433
|
-
) -> algosdk.transaction.Transaction:
|
|
434
|
-
txn = algosdk.transaction.AssetConfigTxn(
|
|
435
|
-
sender=params.sender,
|
|
436
|
-
sp=suggested_params,
|
|
437
|
-
total=params.total,
|
|
438
|
-
default_frozen=params.default_frozen or False,
|
|
439
|
-
unit_name=params.unit_name,
|
|
440
|
-
asset_name=params.asset_name,
|
|
441
|
-
manager=params.manager,
|
|
442
|
-
reserve=params.reserve,
|
|
443
|
-
freeze=params.freeze,
|
|
444
|
-
clawback=params.clawback,
|
|
445
|
-
url=params.url,
|
|
446
|
-
metadata_hash=params.metadata_hash,
|
|
447
|
-
decimals=params.decimals or 0,
|
|
448
|
-
strict_empty_address_check=False,
|
|
449
|
-
) # type: ignore[no-untyped-call]
|
|
450
|
-
|
|
451
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
452
|
-
|
|
453
|
-
def _build_app_call(
|
|
454
|
-
self, params: AppCallParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
455
|
-
) -> algosdk.transaction.Transaction:
|
|
456
|
-
sdk_params = {
|
|
457
|
-
"sender": params.sender,
|
|
458
|
-
"sp": suggested_params,
|
|
459
|
-
"on_complete": params.on_complete or algosdk.transaction.OnComplete.NoOpOC,
|
|
460
|
-
"approval_program": params.approval_program,
|
|
461
|
-
"clear_program": params.clear_program,
|
|
462
|
-
"app_args": params.args,
|
|
463
|
-
"accounts": params.account_references,
|
|
464
|
-
"foreign_apps": params.app_references,
|
|
465
|
-
"foreign_assets": params.asset_references,
|
|
466
|
-
"extra_pages": params.extra_pages,
|
|
467
|
-
"local_schema": algosdk.transaction.StateSchema(
|
|
468
|
-
num_uints=params.schema.get("local_uints", 0), num_byte_slices=params.schema.get("local_byte_slices", 0)
|
|
469
|
-
) # type: ignore[no-untyped-call]
|
|
470
|
-
if params.schema
|
|
471
|
-
else None,
|
|
472
|
-
"global_schema": algosdk.transaction.StateSchema(
|
|
473
|
-
num_uints=params.schema.get("global_uints", 0),
|
|
474
|
-
num_byte_slices=params.schema.get("global_byte_slices", 0),
|
|
475
|
-
) # type: ignore[no-untyped-call]
|
|
476
|
-
if params.schema
|
|
477
|
-
else None,
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
if not params.app_id:
|
|
481
|
-
if params.approval_program is None or params.clear_program is None:
|
|
482
|
-
raise ValueError("approval_program and clear_program are required for application creation")
|
|
483
|
-
|
|
484
|
-
txn = algosdk.transaction.ApplicationCreateTxn(**sdk_params) # type: ignore[no-untyped-call]
|
|
485
|
-
else:
|
|
486
|
-
sdk_params["index"] = params.app_id
|
|
487
|
-
txn = algosdk.transaction.ApplicationCallTxn(**sdk_params) # type: ignore[assignment,no-untyped-call]
|
|
488
|
-
|
|
489
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
490
|
-
|
|
491
|
-
def _build_asset_config(
|
|
492
|
-
self, params: AssetConfigParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
493
|
-
) -> algosdk.transaction.Transaction:
|
|
494
|
-
txn = algosdk.transaction.AssetConfigTxn(
|
|
495
|
-
sender=params.sender,
|
|
496
|
-
sp=suggested_params,
|
|
497
|
-
index=params.asset_id,
|
|
498
|
-
manager=params.manager,
|
|
499
|
-
reserve=params.reserve,
|
|
500
|
-
freeze=params.freeze,
|
|
501
|
-
clawback=params.clawback,
|
|
502
|
-
strict_empty_address_check=False,
|
|
503
|
-
) # type: ignore[no-untyped-call]
|
|
504
|
-
|
|
505
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
506
|
-
|
|
507
|
-
def _build_asset_destroy(
|
|
508
|
-
self, params: AssetDestroyParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
509
|
-
) -> algosdk.transaction.Transaction:
|
|
510
|
-
txn = algosdk.transaction.AssetDestroyTxn(
|
|
511
|
-
sender=params.sender,
|
|
512
|
-
sp=suggested_params,
|
|
513
|
-
index=params.asset_id,
|
|
514
|
-
) # type: ignore[no-untyped-call]
|
|
515
|
-
|
|
516
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
517
|
-
|
|
518
|
-
def _build_asset_freeze(
|
|
519
|
-
self, params: AssetFreezeParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
520
|
-
) -> algosdk.transaction.Transaction:
|
|
521
|
-
txn = algosdk.transaction.AssetFreezeTxn(
|
|
522
|
-
sender=params.sender,
|
|
523
|
-
sp=suggested_params,
|
|
524
|
-
index=params.asset_id,
|
|
525
|
-
target=params.account,
|
|
526
|
-
new_freeze_state=params.frozen,
|
|
527
|
-
) # type: ignore[no-untyped-call]
|
|
528
|
-
|
|
529
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
530
|
-
|
|
531
|
-
def _build_asset_transfer(
|
|
532
|
-
self, params: AssetTransferParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
533
|
-
) -> algosdk.transaction.Transaction:
|
|
534
|
-
txn = algosdk.transaction.AssetTransferTxn(
|
|
535
|
-
sender=params.sender,
|
|
536
|
-
sp=suggested_params,
|
|
537
|
-
receiver=params.receiver,
|
|
538
|
-
amt=params.amount,
|
|
539
|
-
index=params.asset_id,
|
|
540
|
-
close_assets_to=params.close_asset_to,
|
|
541
|
-
revocation_target=params.clawback_target,
|
|
542
|
-
) # type: ignore[no-untyped-call]
|
|
543
|
-
|
|
544
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
545
|
-
|
|
546
|
-
def _build_key_reg(
|
|
547
|
-
self, params: OnlineKeyRegParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
548
|
-
) -> algosdk.transaction.Transaction:
|
|
549
|
-
txn = algosdk.transaction.KeyregTxn(
|
|
550
|
-
sender=params.sender,
|
|
551
|
-
sp=suggested_params,
|
|
552
|
-
votekey=params.vote_key,
|
|
553
|
-
selkey=params.selection_key,
|
|
554
|
-
votefst=params.vote_first,
|
|
555
|
-
votelst=params.vote_last,
|
|
556
|
-
votekd=params.vote_key_dilution,
|
|
557
|
-
rekey_to=params.rekey_to,
|
|
558
|
-
nonpart=False,
|
|
559
|
-
sprfkey=params.state_proof_key,
|
|
560
|
-
) # type: ignore[no-untyped-call]
|
|
561
|
-
|
|
562
|
-
return self._common_txn_build_step(params, txn, suggested_params)
|
|
563
|
-
|
|
564
|
-
def _is_abi_value(self, x: bool | float | str | bytes | list | TxnParams) -> bool:
|
|
565
|
-
if isinstance(x, list):
|
|
566
|
-
return len(x) == 0 or all(self._is_abi_value(item) for item in x)
|
|
567
|
-
|
|
568
|
-
return isinstance(x, bool | int | float | str | bytes)
|
|
569
|
-
|
|
570
|
-
def _build_method_call( # noqa: C901, PLR0912
|
|
571
|
-
self, params: MethodCallParams, suggested_params: algosdk.transaction.SuggestedParams
|
|
572
|
-
) -> list[TransactionWithSigner]:
|
|
573
|
-
method_args = []
|
|
574
|
-
arg_offset = 0
|
|
575
|
-
|
|
576
|
-
if params.args:
|
|
577
|
-
for i, arg in enumerate(params.args):
|
|
578
|
-
if self._is_abi_value(arg):
|
|
579
|
-
method_args.append(arg)
|
|
580
|
-
continue
|
|
581
|
-
|
|
582
|
-
if algosdk.abi.is_abi_transaction_type(params.method.args[i + arg_offset].type):
|
|
583
|
-
match arg:
|
|
584
|
-
case MethodCallParams():
|
|
585
|
-
temp_txn_with_signers = self._build_method_call(arg, suggested_params)
|
|
586
|
-
method_args.extend(temp_txn_with_signers)
|
|
587
|
-
arg_offset += len(temp_txn_with_signers) - 1
|
|
588
|
-
continue
|
|
589
|
-
case AppCallParams():
|
|
590
|
-
txn = self._build_app_call(arg, suggested_params)
|
|
591
|
-
case PayParams():
|
|
592
|
-
txn = self._build_payment(arg, suggested_params)
|
|
593
|
-
case AssetOptInParams():
|
|
594
|
-
txn = self._build_asset_transfer(
|
|
595
|
-
AssetTransferParams(**arg.__dict__, receiver=arg.sender, amount=0), suggested_params
|
|
596
|
-
)
|
|
597
|
-
case AssetCreateParams():
|
|
598
|
-
txn = self._build_asset_create(arg, suggested_params)
|
|
599
|
-
case AssetConfigParams():
|
|
600
|
-
txn = self._build_asset_config(arg, suggested_params)
|
|
601
|
-
case AssetDestroyParams():
|
|
602
|
-
txn = self._build_asset_destroy(arg, suggested_params)
|
|
603
|
-
case AssetFreezeParams():
|
|
604
|
-
txn = self._build_asset_freeze(arg, suggested_params)
|
|
605
|
-
case AssetTransferParams():
|
|
606
|
-
txn = self._build_asset_transfer(arg, suggested_params)
|
|
607
|
-
case OnlineKeyRegParams():
|
|
608
|
-
txn = self._build_key_reg(arg, suggested_params)
|
|
609
|
-
case _:
|
|
610
|
-
raise ValueError(f"Unsupported method arg transaction type: {arg}")
|
|
611
|
-
|
|
612
|
-
method_args.append(
|
|
613
|
-
TransactionWithSigner(txn=txn, signer=params.signer or self.get_signer(params.sender))
|
|
614
|
-
)
|
|
615
|
-
|
|
616
|
-
continue
|
|
617
|
-
|
|
618
|
-
raise ValueError(f"Unsupported method arg: {arg}")
|
|
619
|
-
|
|
620
|
-
method_atc = AtomicTransactionComposer()
|
|
621
|
-
|
|
622
|
-
method_atc.add_method_call(
|
|
623
|
-
app_id=params.app_id or 0,
|
|
624
|
-
method=params.method,
|
|
625
|
-
sender=params.sender,
|
|
626
|
-
sp=suggested_params,
|
|
627
|
-
signer=params.signer or self.get_signer(params.sender),
|
|
628
|
-
method_args=method_args,
|
|
629
|
-
on_complete=algosdk.transaction.OnComplete.NoOpOC,
|
|
630
|
-
note=params.note,
|
|
631
|
-
lease=params.lease,
|
|
632
|
-
)
|
|
633
|
-
|
|
634
|
-
return self._build_atc(method_atc)
|
|
635
|
-
|
|
636
|
-
def _build_txn( # noqa: C901, PLR0912
|
|
637
|
-
self,
|
|
638
|
-
txn: TransactionWithSigner | TxnParams | AtomicTransactionComposer,
|
|
639
|
-
suggested_params: algosdk.transaction.SuggestedParams,
|
|
640
|
-
) -> list[TransactionWithSigner]:
|
|
641
|
-
match txn:
|
|
642
|
-
case TransactionWithSigner():
|
|
643
|
-
return [txn]
|
|
644
|
-
case AtomicTransactionComposer():
|
|
645
|
-
return self._build_atc(txn)
|
|
646
|
-
case MethodCallParams():
|
|
647
|
-
return self._build_method_call(txn, suggested_params)
|
|
648
|
-
|
|
649
|
-
signer = txn.signer or self.get_signer(txn.sender)
|
|
650
|
-
|
|
651
|
-
match txn:
|
|
652
|
-
case PayParams():
|
|
653
|
-
payment = self._build_payment(txn, suggested_params)
|
|
654
|
-
return [TransactionWithSigner(txn=payment, signer=signer)]
|
|
655
|
-
case AssetCreateParams():
|
|
656
|
-
asset_create = self._build_asset_create(txn, suggested_params)
|
|
657
|
-
return [TransactionWithSigner(txn=asset_create, signer=signer)]
|
|
658
|
-
case AppCallParams():
|
|
659
|
-
app_call = self._build_app_call(txn, suggested_params)
|
|
660
|
-
return [TransactionWithSigner(txn=app_call, signer=signer)]
|
|
661
|
-
case AssetConfigParams():
|
|
662
|
-
asset_config = self._build_asset_config(txn, suggested_params)
|
|
663
|
-
return [TransactionWithSigner(txn=asset_config, signer=signer)]
|
|
664
|
-
case AssetDestroyParams():
|
|
665
|
-
asset_destroy = self._build_asset_destroy(txn, suggested_params)
|
|
666
|
-
return [TransactionWithSigner(txn=asset_destroy, signer=signer)]
|
|
667
|
-
case AssetFreezeParams():
|
|
668
|
-
asset_freeze = self._build_asset_freeze(txn, suggested_params)
|
|
669
|
-
return [TransactionWithSigner(txn=asset_freeze, signer=signer)]
|
|
670
|
-
case AssetTransferParams():
|
|
671
|
-
asset_transfer = self._build_asset_transfer(txn, suggested_params)
|
|
672
|
-
return [TransactionWithSigner(txn=asset_transfer, signer=signer)]
|
|
673
|
-
case AssetOptInParams():
|
|
674
|
-
asset_transfer = self._build_asset_transfer(
|
|
675
|
-
AssetTransferParams(**txn.__dict__, receiver=txn.sender, amount=0), suggested_params
|
|
676
|
-
)
|
|
677
|
-
return [TransactionWithSigner(txn=asset_transfer, signer=signer)]
|
|
678
|
-
case OnlineKeyRegParams():
|
|
679
|
-
key_reg = self._build_key_reg(txn, suggested_params)
|
|
680
|
-
return [TransactionWithSigner(txn=key_reg, signer=signer)]
|
|
681
|
-
case _:
|
|
682
|
-
raise ValueError(f"Unsupported txn: {txn}")
|
|
683
|
-
|
|
684
|
-
def build_group(self) -> list[TransactionWithSigner]:
|
|
685
|
-
suggested_params = self.get_suggested_params()
|
|
686
|
-
|
|
687
|
-
txn_with_signers: list[TransactionWithSigner] = []
|
|
688
|
-
|
|
689
|
-
for txn in self.txns:
|
|
690
|
-
txn_with_signers.extend(self._build_txn(txn, suggested_params))
|
|
691
|
-
|
|
692
|
-
for ts in txn_with_signers:
|
|
693
|
-
self.atc.add_transaction(ts)
|
|
694
|
-
|
|
695
|
-
method_calls = {}
|
|
696
|
-
|
|
697
|
-
for i, ts in enumerate(txn_with_signers):
|
|
698
|
-
method = self.txn_method_map.get(ts.txn.get_txid()) # type: ignore[no-untyped-call]
|
|
699
|
-
if method:
|
|
700
|
-
method_calls[i] = method
|
|
701
|
-
|
|
702
|
-
self.atc.method_dict = method_calls
|
|
703
|
-
|
|
704
|
-
return self.atc.build_group()
|
|
705
|
-
|
|
706
|
-
def execute(self, *, max_rounds_to_wait: int | None = None) -> AtomicTransactionResponse:
|
|
707
|
-
group = self.build_group()
|
|
708
|
-
|
|
709
|
-
wait_rounds = max_rounds_to_wait
|
|
710
|
-
|
|
711
|
-
if wait_rounds is None:
|
|
712
|
-
last_round = max(txn.txn.last_valid_round for txn in group)
|
|
713
|
-
first_round = self.get_suggested_params().first
|
|
714
|
-
wait_rounds = last_round - first_round
|
|
715
|
-
|
|
716
|
-
return self.atc.execute(client=self.algod, wait_rounds=wait_rounds)
|
|
9
|
+
handle_getattr(name)
|