algokit-utils 3.0.0b10__py3-none-any.whl → 3.0.0b11__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 +5 -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.0b11.dist-info}/METADATA +1 -1
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b11.dist-info}/RECORD +26 -26
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b11.dist-info}/WHEEL +1 -1
- {algokit_utils-3.0.0b10.dist-info → algokit_utils-3.0.0b11.dist-info}/LICENSE +0 -0
algokit_utils/algorand.py
CHANGED
|
@@ -58,6 +58,8 @@ class AlgorandClient:
|
|
|
58
58
|
|
|
59
59
|
:param validity_window: The number of rounds between the first and last valid rounds
|
|
60
60
|
:return: The `AlgorandClient` so method calls can be chained
|
|
61
|
+
:example:
|
|
62
|
+
>>> algorand = AlgorandClient.mainnet().set_default_validity_window(1000);
|
|
61
63
|
"""
|
|
62
64
|
self._default_validity_window = validity_window
|
|
63
65
|
return self
|
|
@@ -70,6 +72,9 @@ class AlgorandClient:
|
|
|
70
72
|
|
|
71
73
|
:param signer: The signer to use, either a `TransactionSigner` or a `TransactionSignerAccountProtocol`
|
|
72
74
|
:return: The `AlgorandClient` so method calls can be chained
|
|
75
|
+
:example:
|
|
76
|
+
>>> signer = SigningAccount(private_key=..., address=...)
|
|
77
|
+
>>> algorand = AlgorandClient.mainnet().set_default_signer(signer)
|
|
73
78
|
"""
|
|
74
79
|
self._account_manager.set_default_signer(signer)
|
|
75
80
|
return self
|
|
@@ -81,21 +86,31 @@ class AlgorandClient:
|
|
|
81
86
|
:param sender: The sender address to use this signer for
|
|
82
87
|
:param signer: The signer to sign transactions with for the given sender
|
|
83
88
|
:return: The `AlgorandClient` so method calls can be chained
|
|
89
|
+
:example:
|
|
90
|
+
>>> signer = SigningAccount(private_key=..., address=...)
|
|
91
|
+
>>> algorand = AlgorandClient.mainnet().set_signer(signer.addr, signer.signer)
|
|
84
92
|
"""
|
|
85
93
|
self._account_manager.set_signer(sender, signer)
|
|
86
94
|
return self
|
|
87
95
|
|
|
88
|
-
def
|
|
96
|
+
def set_signer_from_account(self, signer: TransactionSignerAccountProtocol) -> typing_extensions.Self:
|
|
89
97
|
"""
|
|
90
98
|
Sets the default signer to use if no other signer is specified.
|
|
91
99
|
|
|
92
100
|
:param signer: The signer to use, either a `TransactionSigner` or a `TransactionSignerAccountProtocol`
|
|
93
101
|
:return: The `AlgorandClient` so method calls can be chained
|
|
102
|
+
:example:
|
|
103
|
+
>>> accountManager = AlgorandClient.mainnet()
|
|
104
|
+
>>> accountManager.set_signer_from_account(TransactionSignerAccount(address=..., signer=...))
|
|
105
|
+
>>> accountManager.set_signer_from_account(algosdk.LogicSigAccount(program, args))
|
|
106
|
+
>>> accountManager.set_signer_from_account(SigningAccount(private_key=..., address=...))
|
|
107
|
+
>>> accountManager.set_signer_from_account(MultisigAccount(metadata, signing_accounts))
|
|
108
|
+
>>> accountManager.set_signer_from_account(account)
|
|
94
109
|
"""
|
|
95
110
|
self._account_manager.set_default_signer(signer)
|
|
96
111
|
return self
|
|
97
112
|
|
|
98
|
-
def
|
|
113
|
+
def set_suggested_params_cache(
|
|
99
114
|
self, suggested_params: SuggestedParams, until: float | None = None
|
|
100
115
|
) -> typing_extensions.Self:
|
|
101
116
|
"""
|
|
@@ -104,23 +119,32 @@ class AlgorandClient:
|
|
|
104
119
|
:param suggested_params: The suggested params to use
|
|
105
120
|
:param until: A timestamp until which to cache, or if not specified then the timeout is used
|
|
106
121
|
:return: The `AlgorandClient` so method calls can be chained
|
|
122
|
+
:example:
|
|
123
|
+
>>> algorand = AlgorandClient.mainnet().set_suggested_params_cache(suggested_params, time.time() + 3.6e6)
|
|
107
124
|
"""
|
|
108
125
|
self._cached_suggested_params = suggested_params
|
|
109
126
|
self._cached_suggested_params_expiry = until or time.time() + self._cached_suggested_params_timeout
|
|
110
127
|
return self
|
|
111
128
|
|
|
112
|
-
def
|
|
129
|
+
def set_suggested_params_cache_timeout(self, timeout: int) -> typing_extensions.Self:
|
|
113
130
|
"""
|
|
114
131
|
Sets the timeout for caching suggested params.
|
|
115
132
|
|
|
116
133
|
:param timeout: The timeout in milliseconds
|
|
117
134
|
:return: The `AlgorandClient` so method calls can be chained
|
|
135
|
+
:example:
|
|
136
|
+
>>> algorand = AlgorandClient.mainnet().set_suggested_params_cache_timeout(10_000)
|
|
118
137
|
"""
|
|
119
138
|
self._cached_suggested_params_timeout = timeout
|
|
120
139
|
return self
|
|
121
140
|
|
|
122
141
|
def get_suggested_params(self) -> SuggestedParams:
|
|
123
|
-
"""
|
|
142
|
+
"""
|
|
143
|
+
Get suggested params for a transaction (either cached or from algod if the cache is stale or empty)
|
|
144
|
+
|
|
145
|
+
:example:
|
|
146
|
+
>>> algorand = AlgorandClient.mainnet().get_suggested_params()
|
|
147
|
+
"""
|
|
124
148
|
if self._cached_suggested_params and (
|
|
125
149
|
self._cached_suggested_params_expiry is None or self._cached_suggested_params_expiry > time.time()
|
|
126
150
|
):
|
|
@@ -132,7 +156,14 @@ class AlgorandClient:
|
|
|
132
156
|
return copy.deepcopy(self._cached_suggested_params)
|
|
133
157
|
|
|
134
158
|
def new_group(self) -> TransactionComposer:
|
|
135
|
-
"""
|
|
159
|
+
"""
|
|
160
|
+
Start a new `TransactionComposer` transaction group
|
|
161
|
+
|
|
162
|
+
:example:
|
|
163
|
+
>>> composer = AlgorandClient.mainnet().new_group()
|
|
164
|
+
>>> result = await composer.add_transaction(payment).send()
|
|
165
|
+
"""
|
|
166
|
+
|
|
136
167
|
return TransactionComposer(
|
|
137
168
|
algod=self.client.algod,
|
|
138
169
|
get_signer=lambda addr: self.account.get_signer(addr),
|
|
@@ -142,36 +173,81 @@ class AlgorandClient:
|
|
|
142
173
|
|
|
143
174
|
@property
|
|
144
175
|
def client(self) -> ClientManager:
|
|
145
|
-
"""
|
|
176
|
+
"""
|
|
177
|
+
Get clients, including algosdk clients and app clients.
|
|
178
|
+
|
|
179
|
+
:example:
|
|
180
|
+
>>> clientManager = AlgorandClient.mainnet().client
|
|
181
|
+
"""
|
|
146
182
|
return self._client_manager
|
|
147
183
|
|
|
148
184
|
@property
|
|
149
185
|
def account(self) -> AccountManager:
|
|
150
|
-
"""Get or create accounts that can sign transactions.
|
|
186
|
+
"""Get or create accounts that can sign transactions.
|
|
187
|
+
|
|
188
|
+
:example:
|
|
189
|
+
>>> accountManager = AlgorandClient.mainnet().account
|
|
190
|
+
"""
|
|
151
191
|
return self._account_manager
|
|
152
192
|
|
|
153
193
|
@property
|
|
154
194
|
def asset(self) -> AssetManager:
|
|
155
|
-
"""
|
|
195
|
+
"""
|
|
196
|
+
Get or create assets.
|
|
197
|
+
|
|
198
|
+
:example:
|
|
199
|
+
>>> assetManager = AlgorandClient.mainnet().asset
|
|
200
|
+
"""
|
|
156
201
|
return self._asset_manager
|
|
157
202
|
|
|
158
203
|
@property
|
|
159
204
|
def app(self) -> AppManager:
|
|
205
|
+
"""
|
|
206
|
+
Get or create applications.
|
|
207
|
+
|
|
208
|
+
:example:
|
|
209
|
+
>>> appManager = AlgorandClient.mainnet().app
|
|
210
|
+
"""
|
|
160
211
|
return self._app_manager
|
|
161
212
|
|
|
162
213
|
@property
|
|
163
214
|
def app_deployer(self) -> AppDeployer:
|
|
164
|
-
"""
|
|
215
|
+
"""
|
|
216
|
+
Get or create applications.
|
|
217
|
+
|
|
218
|
+
:example:
|
|
219
|
+
>>> appDeployer = AlgorandClient.mainnet().app_deployer
|
|
220
|
+
"""
|
|
165
221
|
return self._app_deployer
|
|
166
222
|
|
|
167
223
|
@property
|
|
168
224
|
def send(self) -> AlgorandClientTransactionSender:
|
|
169
|
-
"""
|
|
225
|
+
"""
|
|
226
|
+
Methods for sending a transaction and waiting for confirmation
|
|
227
|
+
|
|
228
|
+
:example:
|
|
229
|
+
>>> result = await AlgorandClient.mainnet().send.payment(
|
|
230
|
+
>>> PaymentParams(
|
|
231
|
+
>>> sender="SENDERADDRESS",
|
|
232
|
+
>>> receiver="RECEIVERADDRESS",
|
|
233
|
+
>>> amount=AlgoAmount(algo-1)
|
|
234
|
+
>>> ))
|
|
235
|
+
"""
|
|
170
236
|
return self._transaction_sender
|
|
171
237
|
|
|
172
238
|
@property
|
|
173
239
|
def create_transaction(self) -> AlgorandClientTransactionCreator:
|
|
174
|
-
"""
|
|
240
|
+
"""
|
|
241
|
+
Methods for building transactions
|
|
242
|
+
|
|
243
|
+
:example:
|
|
244
|
+
>>> transaction = AlgorandClient.mainnet().create_transaction.payment(
|
|
245
|
+
>>> PaymentParams(
|
|
246
|
+
>>> sender="SENDERADDRESS",
|
|
247
|
+
>>> receiver="RECEIVERADDRESS",
|
|
248
|
+
>>> amount=AlgoAmount(algo=1)
|
|
249
|
+
>>> ))
|
|
250
|
+
"""
|
|
175
251
|
return self._transaction_creator
|
|
176
252
|
|
|
177
253
|
@staticmethod
|
|
@@ -180,6 +256,9 @@ class AlgorandClient:
|
|
|
180
256
|
Returns an `AlgorandClient` pointing at default LocalNet ports and API token.
|
|
181
257
|
|
|
182
258
|
:return: The `AlgorandClient`
|
|
259
|
+
|
|
260
|
+
:example:
|
|
261
|
+
>>> algorand = AlgorandClient.default_localnet()
|
|
183
262
|
"""
|
|
184
263
|
return AlgorandClient(
|
|
185
264
|
AlgoClientConfigs(
|
|
@@ -195,6 +274,9 @@ class AlgorandClient:
|
|
|
195
274
|
Returns an `AlgorandClient` pointing at TestNet using AlgoNode.
|
|
196
275
|
|
|
197
276
|
:return: The `AlgorandClient`
|
|
277
|
+
|
|
278
|
+
:example:
|
|
279
|
+
>>> algorand = AlgorandClient.testnet()
|
|
198
280
|
"""
|
|
199
281
|
return AlgorandClient(
|
|
200
282
|
AlgoClientConfigs(
|
|
@@ -210,6 +292,9 @@ class AlgorandClient:
|
|
|
210
292
|
Returns an `AlgorandClient` pointing at MainNet using AlgoNode.
|
|
211
293
|
|
|
212
294
|
:return: The `AlgorandClient`
|
|
295
|
+
|
|
296
|
+
:example:
|
|
297
|
+
>>> algorand = AlgorandClient.mainnet()
|
|
213
298
|
"""
|
|
214
299
|
return AlgorandClient(
|
|
215
300
|
AlgoClientConfigs(
|
|
@@ -230,6 +315,9 @@ class AlgorandClient:
|
|
|
230
315
|
:param indexer: The indexer client to use
|
|
231
316
|
:param kmd: The kmd client to use
|
|
232
317
|
:return: The `AlgorandClient`
|
|
318
|
+
|
|
319
|
+
:example:
|
|
320
|
+
>>> algorand = AlgorandClient.from_clients(algod, indexer, kmd)
|
|
233
321
|
"""
|
|
234
322
|
return AlgorandClient(AlgoSdkClients(algod=algod, indexer=indexer, kmd=kmd))
|
|
235
323
|
|
|
@@ -243,6 +331,9 @@ class AlgorandClient:
|
|
|
243
331
|
Expects to be called from a Python environment.
|
|
244
332
|
|
|
245
333
|
:return: The `AlgorandClient`
|
|
334
|
+
|
|
335
|
+
:example:
|
|
336
|
+
>>> algorand = AlgorandClient.from_environment()
|
|
246
337
|
"""
|
|
247
338
|
return AlgorandClient(ClientManager.get_config_from_environment_or_localnet())
|
|
248
339
|
|
|
@@ -259,6 +350,9 @@ class AlgorandClient:
|
|
|
259
350
|
:param indexer_config: The config to use for the indexer client
|
|
260
351
|
:param kmd_config: The config to use for the kmd client
|
|
261
352
|
:return: The `AlgorandClient`
|
|
353
|
+
|
|
354
|
+
:example:
|
|
355
|
+
>>> algorand = AlgorandClient.from_config(algod_config, indexer_config, kmd_config)
|
|
262
356
|
"""
|
|
263
357
|
return AlgorandClient(
|
|
264
358
|
AlgoClientConfigs(algod_config=algod_config, indexer_config=indexer_config, kmd_config=kmd_config)
|
|
@@ -7,7 +7,7 @@ warnings.warn(
|
|
|
7
7
|
Use `from algokit_utils.applications.app_spec.arc32 import ...` to access Arc32 app spec instead.
|
|
8
8
|
By default, the ARC52Contract is a recommended app spec to use, serving as a replacement
|
|
9
9
|
for legacy 'ApplicationSpecification' class.
|
|
10
|
-
To convert legacy app specs to ARC52, use `
|
|
10
|
+
To convert legacy app specs to ARC52, use `Arc56Contract.from_arc32`.
|
|
11
11
|
""",
|
|
12
12
|
DeprecationWarning,
|
|
13
13
|
stacklevel=2,
|
|
@@ -45,20 +45,18 @@ class ABIReturn:
|
|
|
45
45
|
"""Represents the return value from an ABI method call.
|
|
46
46
|
|
|
47
47
|
Wraps the raw return value and decoded value along with any decode errors.
|
|
48
|
-
|
|
49
|
-
:ivar result: The ABIResult object containing the method call results
|
|
50
|
-
:ivar raw_value: The raw return value from the method call
|
|
51
|
-
:ivar value: The decoded return value from the method call
|
|
52
|
-
:ivar method: The ABI method definition
|
|
53
|
-
:ivar decode_error: The exception that occurred during decoding, if any
|
|
54
|
-
:ivar tx_info: The transaction info for the method call from raw algosdk `ABIResult`
|
|
55
48
|
"""
|
|
56
49
|
|
|
57
50
|
raw_value: bytes | None = None
|
|
51
|
+
"""The raw return value from the method call"""
|
|
58
52
|
value: ABIValue | None = None
|
|
53
|
+
"""The decoded return value from the method call"""
|
|
59
54
|
method: AlgorandABIMethod | None = None
|
|
55
|
+
"""The ABI method definition"""
|
|
60
56
|
decode_error: Exception | None = None
|
|
57
|
+
"""The exception that occurred during decoding, if any"""
|
|
61
58
|
tx_info: dict[str, Any] | None = None
|
|
59
|
+
"""The transaction info for the method call from raw algosdk `ABIResult`"""
|
|
62
60
|
|
|
63
61
|
def __init__(self, result: ABIResult) -> None:
|
|
64
62
|
self.decode_error = result.decode_error
|
|
@@ -269,11 +267,9 @@ def get_abi_struct_from_abi_tuple(
|
|
|
269
267
|
|
|
270
268
|
@dataclass(kw_only=True, frozen=True)
|
|
271
269
|
class BoxABIValue:
|
|
272
|
-
"""Represents an ABI value stored in a box.
|
|
273
|
-
|
|
274
|
-
:ivar name: The name of the box
|
|
275
|
-
:ivar value: The ABI value stored in the box
|
|
276
|
-
"""
|
|
270
|
+
"""Represents an ABI value stored in a box."""
|
|
277
271
|
|
|
278
272
|
name: BoxName
|
|
273
|
+
"""The name of the box"""
|
|
279
274
|
value: ABIValue
|
|
275
|
+
"""The ABI value stored in the box"""
|
|
@@ -177,17 +177,16 @@ class AppClientCompilationResult:
|
|
|
177
177
|
"""Result of compiling an application's TEAL code.
|
|
178
178
|
|
|
179
179
|
Contains the compiled approval and clear state programs along with optional compilation artifacts.
|
|
180
|
-
|
|
181
|
-
:ivar approval_program: The compiled approval program bytes
|
|
182
|
-
:ivar clear_state_program: The compiled clear state program bytes
|
|
183
|
-
:ivar compiled_approval: Optional compilation artifacts for approval program
|
|
184
|
-
:ivar compiled_clear: Optional compilation artifacts for clear state program
|
|
185
180
|
"""
|
|
186
181
|
|
|
187
182
|
approval_program: bytes
|
|
183
|
+
"""The compiled approval program bytes"""
|
|
188
184
|
clear_state_program: bytes
|
|
185
|
+
"""The compiled clear state program bytes"""
|
|
189
186
|
compiled_approval: CompiledTeal | None = None
|
|
187
|
+
"""Optional compilation artifacts for approval program"""
|
|
190
188
|
compiled_clear: CompiledTeal | None = None
|
|
189
|
+
"""Optional compilation artifacts for clear state program"""
|
|
191
190
|
|
|
192
191
|
|
|
193
192
|
class AppClientCompilationParams(TypedDict, total=False):
|
|
@@ -209,52 +208,50 @@ MethodT = TypeVar("MethodT")
|
|
|
209
208
|
|
|
210
209
|
@dataclass(kw_only=True, frozen=True)
|
|
211
210
|
class CommonAppCallParams:
|
|
212
|
-
"""Common configuration for app call transaction parameters
|
|
213
|
-
|
|
214
|
-
:ivar account_references: List of account addresses to reference
|
|
215
|
-
:ivar app_references: List of app IDs to reference
|
|
216
|
-
:ivar asset_references: List of asset IDs to reference
|
|
217
|
-
:ivar box_references: List of box references to include
|
|
218
|
-
:ivar extra_fee: Additional fee to add to transaction
|
|
219
|
-
:ivar lease: Transaction lease value
|
|
220
|
-
:ivar max_fee: Maximum fee allowed for transaction
|
|
221
|
-
:ivar note: Arbitrary note for the transaction
|
|
222
|
-
:ivar rekey_to: Address to rekey account to
|
|
223
|
-
:ivar sender: Sender address override
|
|
224
|
-
:ivar signer: Custom transaction signer
|
|
225
|
-
:ivar static_fee: Fixed fee for transaction
|
|
226
|
-
:ivar validity_window: Number of rounds valid
|
|
227
|
-
:ivar first_valid_round: First valid round number
|
|
228
|
-
:ivar last_valid_round: Last valid round number"""
|
|
211
|
+
"""Common configuration for app call transaction parameters"""
|
|
229
212
|
|
|
230
213
|
account_references: list[str] | None = None
|
|
214
|
+
"""List of account addresses to reference"""
|
|
231
215
|
app_references: list[int] | None = None
|
|
216
|
+
"""List of app IDs to reference"""
|
|
232
217
|
asset_references: list[int] | None = None
|
|
218
|
+
"""List of asset IDs to reference"""
|
|
233
219
|
box_references: list[BoxReference | BoxIdentifier] | None = None
|
|
220
|
+
"""List of box references to include"""
|
|
234
221
|
extra_fee: AlgoAmount | None = None
|
|
222
|
+
"""Additional fee to add to transaction"""
|
|
235
223
|
lease: bytes | None = None
|
|
224
|
+
"""Transaction lease value"""
|
|
236
225
|
max_fee: AlgoAmount | None = None
|
|
226
|
+
"""Maximum fee allowed for transaction"""
|
|
237
227
|
note: bytes | None = None
|
|
228
|
+
"""Custom note for the transaction"""
|
|
238
229
|
rekey_to: str | None = None
|
|
230
|
+
"""Address to rekey account to"""
|
|
239
231
|
sender: str | None = None
|
|
232
|
+
"""Sender address override"""
|
|
240
233
|
signer: TransactionSigner | None = None
|
|
234
|
+
"""Custom transaction signer"""
|
|
241
235
|
static_fee: AlgoAmount | None = None
|
|
236
|
+
"""Fixed fee for transaction"""
|
|
242
237
|
validity_window: int | None = None
|
|
238
|
+
"""Number of rounds valid"""
|
|
243
239
|
first_valid_round: int | None = None
|
|
240
|
+
"""First valid round number"""
|
|
244
241
|
last_valid_round: int | None = None
|
|
242
|
+
"""Last valid round number"""
|
|
245
243
|
on_complete: OnComplete | None = None
|
|
244
|
+
"""Optional on complete action"""
|
|
246
245
|
|
|
247
246
|
|
|
248
247
|
@dataclass(frozen=True)
|
|
249
248
|
class AppClientCreateSchema:
|
|
250
|
-
"""Schema for application creation.
|
|
251
|
-
|
|
252
|
-
:ivar extra_program_pages: Optional number of extra program pages
|
|
253
|
-
:ivar schema: Optional application creation schema
|
|
254
|
-
"""
|
|
249
|
+
"""Schema for application creation."""
|
|
255
250
|
|
|
256
251
|
extra_program_pages: int | None = None
|
|
252
|
+
"""Optional number of extra program pages"""
|
|
257
253
|
schema: AppCreateSchema | None = None
|
|
254
|
+
"""Optional application creation schema"""
|
|
258
255
|
|
|
259
256
|
|
|
260
257
|
@dataclass(kw_only=True, frozen=True)
|
|
@@ -262,28 +259,25 @@ class CommonAppCallCreateParams(AppClientCreateSchema, CommonAppCallParams):
|
|
|
262
259
|
"""Common configuration for app create call transaction parameters."""
|
|
263
260
|
|
|
264
261
|
on_complete: CreateOnComplete | None = None
|
|
262
|
+
"""Optional on complete action"""
|
|
265
263
|
|
|
266
264
|
|
|
267
265
|
@dataclass(kw_only=True, frozen=True)
|
|
268
266
|
class FundAppAccountParams(CommonAppCallParams):
|
|
269
|
-
"""Parameters for funding an application's account.
|
|
270
|
-
|
|
271
|
-
:ivar amount: Amount to fund
|
|
272
|
-
:ivar close_remainder_to: Optional address to close remainder to
|
|
273
|
-
"""
|
|
267
|
+
"""Parameters for funding an application's account."""
|
|
274
268
|
|
|
275
269
|
amount: AlgoAmount
|
|
270
|
+
"""Amount to fund"""
|
|
276
271
|
close_remainder_to: str | None = None
|
|
272
|
+
"""Optional address to close remainder to"""
|
|
277
273
|
|
|
278
274
|
|
|
279
275
|
@dataclass(kw_only=True, frozen=True)
|
|
280
276
|
class AppClientBareCallParams(CommonAppCallParams):
|
|
281
|
-
"""Parameters for bare application calls.
|
|
282
|
-
|
|
283
|
-
:ivar args: Optional arguments
|
|
284
|
-
"""
|
|
277
|
+
"""Parameters for bare application calls."""
|
|
285
278
|
|
|
286
279
|
args: list[bytes] | None = None
|
|
280
|
+
"""Optional arguments"""
|
|
287
281
|
|
|
288
282
|
|
|
289
283
|
@dataclass(frozen=True)
|
|
@@ -291,19 +285,17 @@ class AppClientBareCallCreateParams(CommonAppCallCreateParams):
|
|
|
291
285
|
"""Parameters for creating application with bare call."""
|
|
292
286
|
|
|
293
287
|
on_complete: CreateOnComplete | None = None
|
|
288
|
+
"""Optional on complete action"""
|
|
294
289
|
|
|
295
290
|
|
|
296
291
|
@dataclass(kw_only=True, frozen=True)
|
|
297
292
|
class BaseAppClientMethodCallParams(Generic[ArgsT, MethodT], CommonAppCallParams):
|
|
298
|
-
"""Base parameters for application method calls.
|
|
299
|
-
|
|
300
|
-
:ivar method: Method to call
|
|
301
|
-
:ivar args: Optional arguments to pass to method
|
|
302
|
-
:ivar on_complete: Optional on complete action
|
|
303
|
-
"""
|
|
293
|
+
"""Base parameters for application method calls."""
|
|
304
294
|
|
|
305
295
|
method: MethodT
|
|
296
|
+
"""Method to call"""
|
|
306
297
|
args: ArgsT | None = None
|
|
298
|
+
"""Arguments to pass to the application method call"""
|
|
307
299
|
|
|
308
300
|
|
|
309
301
|
@dataclass(kw_only=True, frozen=True)
|
|
@@ -321,6 +313,7 @@ class AppClientMethodCallCreateParams(AppClientCreateSchema, AppClientMethodCall
|
|
|
321
313
|
"""Parameters for creating application with method call"""
|
|
322
314
|
|
|
323
315
|
on_complete: CreateOnComplete | None = None
|
|
316
|
+
"""Optional on complete action"""
|
|
324
317
|
|
|
325
318
|
|
|
326
319
|
class _AppClientStateMethods:
|
|
@@ -1261,13 +1254,21 @@ class AppClientParams:
|
|
|
1261
1254
|
"""Full parameters for creating an app client"""
|
|
1262
1255
|
|
|
1263
1256
|
app_spec: Arc56Contract | Arc32Contract | str
|
|
1257
|
+
"""The application specification"""
|
|
1264
1258
|
algorand: AlgorandClient
|
|
1259
|
+
"""The Algorand client"""
|
|
1265
1260
|
app_id: int
|
|
1261
|
+
"""The application ID"""
|
|
1266
1262
|
app_name: str | None = None
|
|
1263
|
+
"""The application name"""
|
|
1267
1264
|
default_sender: str | None = None
|
|
1265
|
+
"""The default sender address"""
|
|
1268
1266
|
default_signer: TransactionSigner | None = None
|
|
1267
|
+
"""The default transaction signer"""
|
|
1269
1268
|
approval_source_map: SourceMap | None = None
|
|
1269
|
+
"""The approval source map"""
|
|
1270
1270
|
clear_source_map: SourceMap | None = None
|
|
1271
|
+
"""The clear source map"""
|
|
1271
1272
|
|
|
1272
1273
|
|
|
1273
1274
|
class AppClient:
|
|
@@ -1277,6 +1278,26 @@ class AppClient:
|
|
|
1277
1278
|
methods for calling application methods, managing state, and handling transactions.
|
|
1278
1279
|
|
|
1279
1280
|
:param params: Parameters for creating the app client
|
|
1281
|
+
|
|
1282
|
+
:example:
|
|
1283
|
+
>>> params = AppClientParams(
|
|
1284
|
+
... app_spec=Arc56Contract.from_json(app_spec_json),
|
|
1285
|
+
... algorand=algorand,
|
|
1286
|
+
... app_id=1234567890,
|
|
1287
|
+
... app_name="My App",
|
|
1288
|
+
... default_sender="SENDERADDRESS",
|
|
1289
|
+
... default_signer=TransactionSigner(
|
|
1290
|
+
... account="SIGNERACCOUNT",
|
|
1291
|
+
... private_key="SIGNERPRIVATEKEY",
|
|
1292
|
+
... ),
|
|
1293
|
+
... approval_source_map=SourceMap(
|
|
1294
|
+
... source="APPROVALSOURCE",
|
|
1295
|
+
... ),
|
|
1296
|
+
... clear_source_map=SourceMap(
|
|
1297
|
+
... source="CLEARSOURCE",
|
|
1298
|
+
... ),
|
|
1299
|
+
... )
|
|
1300
|
+
>>> client = AppClient(params)
|
|
1280
1301
|
"""
|
|
1281
1302
|
|
|
1282
1303
|
def __init__(self, params: AppClientParams) -> None:
|
|
@@ -1347,6 +1368,19 @@ class AppClient:
|
|
|
1347
1368
|
"""Get the method parameters builder.
|
|
1348
1369
|
|
|
1349
1370
|
:return: The method parameters builder for this application
|
|
1371
|
+
|
|
1372
|
+
:example:
|
|
1373
|
+
>>> # Create a transaction in the future using Algorand Client
|
|
1374
|
+
>>> my_method_call = app_client.params.call(AppClientMethodCallParams(
|
|
1375
|
+
method='my_method',
|
|
1376
|
+
args=[123, 'hello']))
|
|
1377
|
+
>>> # ...
|
|
1378
|
+
>>> await algorand.send.AppMethodCall(my_method_call)
|
|
1379
|
+
>>> # Define a nested transaction as an ABI argument
|
|
1380
|
+
>>> my_method_call = app_client.params.call(AppClientMethodCallParams(
|
|
1381
|
+
method='my_method',
|
|
1382
|
+
args=[123, 'hello']))
|
|
1383
|
+
>>> app_client.send.call(AppClientMethodCallParams(method='my_method2', args=[my_method_call]))
|
|
1350
1384
|
"""
|
|
1351
1385
|
return self._params_accessor
|
|
1352
1386
|
|
|
@@ -1370,9 +1404,13 @@ class AppClient:
|
|
|
1370
1404
|
def normalise_app_spec(app_spec: Arc56Contract | Arc32Contract | str) -> Arc56Contract:
|
|
1371
1405
|
"""Normalize an application specification to ARC-56 format.
|
|
1372
1406
|
|
|
1373
|
-
:param app_spec: The application specification to normalize
|
|
1407
|
+
:param app_spec: The application specification to normalize. Can be raw arc32 or arc56 json,
|
|
1408
|
+
or an Arc32Contract or Arc56Contract instance
|
|
1374
1409
|
:return: The normalized ARC-56 contract specification
|
|
1375
1410
|
:raises ValueError: If the app spec format is invalid
|
|
1411
|
+
|
|
1412
|
+
:example:
|
|
1413
|
+
>>> spec = AppClient.normalise_app_spec(app_spec_json)
|
|
1376
1414
|
"""
|
|
1377
1415
|
if isinstance(app_spec, str):
|
|
1378
1416
|
spec_dict = json.loads(app_spec)
|
|
@@ -1411,6 +1449,24 @@ class AppClient:
|
|
|
1411
1449
|
:param clear_source_map: Optional clear program source map
|
|
1412
1450
|
:return: A new AppClient instance
|
|
1413
1451
|
:raises Exception: If no app ID is found for the network
|
|
1452
|
+
|
|
1453
|
+
:example:
|
|
1454
|
+
>>> client = AppClient.from_network(
|
|
1455
|
+
... app_spec=Arc56Contract.from_json(app_spec_json),
|
|
1456
|
+
... algorand=algorand,
|
|
1457
|
+
... app_name="My App",
|
|
1458
|
+
... default_sender="SENDERADDRESS",
|
|
1459
|
+
... default_signer=TransactionSigner(
|
|
1460
|
+
... account="SIGNERACCOUNT",
|
|
1461
|
+
... private_key="SIGNERPRIVATEKEY",
|
|
1462
|
+
... ),
|
|
1463
|
+
... approval_source_map=SourceMap(
|
|
1464
|
+
... source="APPROVALSOURCE",
|
|
1465
|
+
... ),
|
|
1466
|
+
... clear_source_map=SourceMap(
|
|
1467
|
+
... source="CLEARSOURCE",
|
|
1468
|
+
... ),
|
|
1469
|
+
... )
|
|
1414
1470
|
"""
|
|
1415
1471
|
network = algorand.client.network()
|
|
1416
1472
|
app_spec = AppClient.normalise_app_spec(app_spec)
|
|
@@ -1471,6 +1527,14 @@ class AppClient:
|
|
|
1471
1527
|
:param app_lookup_cache: Optional app lookup cache
|
|
1472
1528
|
:return: A new AppClient instance
|
|
1473
1529
|
:raises ValueError: If the app is not found for the creator and name
|
|
1530
|
+
|
|
1531
|
+
:example:
|
|
1532
|
+
>>> client = AppClient.from_creator_and_name(
|
|
1533
|
+
... creator_address="CREATORADDRESS",
|
|
1534
|
+
... app_name="APPNAME",
|
|
1535
|
+
... app_spec=Arc56Contract.from_json(app_spec_json),
|
|
1536
|
+
... algorand=algorand,
|
|
1537
|
+
... )
|
|
1474
1538
|
"""
|
|
1475
1539
|
app_spec_ = AppClient.normalise_app_spec(app_spec)
|
|
1476
1540
|
app_lookup = app_lookup_cache or algorand.app_deployer.get_creator_apps_by_name(
|
|
@@ -1693,7 +1757,11 @@ class AppClient:
|
|
|
1693
1757
|
:param default_signer: Optional new default signer
|
|
1694
1758
|
:param approval_source_map: Optional new approval source map
|
|
1695
1759
|
:param clear_source_map: Optional new clear source map
|
|
1696
|
-
:return: A new AppClient instance
|
|
1760
|
+
:return: A new AppClient instance
|
|
1761
|
+
|
|
1762
|
+
:example:
|
|
1763
|
+
>>> client = AppClient(params)
|
|
1764
|
+
>>> cloned_client = client.clone(app_name="Cloned App", default_sender="NEW_SENDER")
|
|
1697
1765
|
"""
|
|
1698
1766
|
return AppClient(
|
|
1699
1767
|
AppClientParams(
|
|
@@ -1770,6 +1838,8 @@ class AppClient:
|
|
|
1770
1838
|
"""Get the application's global state.
|
|
1771
1839
|
|
|
1772
1840
|
:return: The application's global state
|
|
1841
|
+
:example:
|
|
1842
|
+
>>> global_state = client.get_global_state()
|
|
1773
1843
|
"""
|
|
1774
1844
|
return self._state_accessor.get_global_state()
|
|
1775
1845
|
|
|
@@ -1777,6 +1847,9 @@ class AppClient:
|
|
|
1777
1847
|
"""Get all box names for the application.
|
|
1778
1848
|
|
|
1779
1849
|
:return: List of box names
|
|
1850
|
+
|
|
1851
|
+
:example:
|
|
1852
|
+
>>> box_names = client.get_box_names()
|
|
1780
1853
|
"""
|
|
1781
1854
|
return self._algorand.app.get_box_names(self._app_id)
|
|
1782
1855
|
|
|
@@ -1785,6 +1858,9 @@ class AppClient:
|
|
|
1785
1858
|
|
|
1786
1859
|
:param name: The box identifier
|
|
1787
1860
|
:return: The box value as bytes
|
|
1861
|
+
|
|
1862
|
+
:example:
|
|
1863
|
+
>>> box_value = client.get_box_value(box_name)
|
|
1788
1864
|
"""
|
|
1789
1865
|
return self._algorand.app.get_box_value(self._app_id, name)
|
|
1790
1866
|
|
|
@@ -1794,6 +1870,9 @@ class AppClient:
|
|
|
1794
1870
|
:param name: The box identifier
|
|
1795
1871
|
:param abi_type: The ABI type to decode as
|
|
1796
1872
|
:return: The decoded box value
|
|
1873
|
+
|
|
1874
|
+
:example:
|
|
1875
|
+
>>> box_value = client.get_box_value_from_abi_type(box_name, abi_type)
|
|
1797
1876
|
"""
|
|
1798
1877
|
return self._algorand.app.get_box_value_from_abi_type(self._app_id, name, abi_type)
|
|
1799
1878
|
|
|
@@ -1802,6 +1881,9 @@ class AppClient:
|
|
|
1802
1881
|
|
|
1803
1882
|
:param filter_func: Optional function to filter box names
|
|
1804
1883
|
:return: List of box values
|
|
1884
|
+
|
|
1885
|
+
:example:
|
|
1886
|
+
>>> box_values = client.get_box_values()
|
|
1805
1887
|
"""
|
|
1806
1888
|
names = [n for n in self.get_box_names() if not filter_func or filter_func(n)]
|
|
1807
1889
|
values = self._algorand.app.get_box_values(self.app_id, [n.name_raw for n in names])
|
|
@@ -1815,6 +1897,9 @@ class AppClient:
|
|
|
1815
1897
|
:param abi_type: The ABI type to decode as
|
|
1816
1898
|
:param filter_func: Optional function to filter box names
|
|
1817
1899
|
:return: List of decoded box values
|
|
1900
|
+
|
|
1901
|
+
:example:
|
|
1902
|
+
>>> box_values = client.get_box_values_from_abi_type(abi_type)
|
|
1818
1903
|
"""
|
|
1819
1904
|
names = self.get_box_names()
|
|
1820
1905
|
if filter_func:
|
|
@@ -1834,6 +1919,9 @@ class AppClient:
|
|
|
1834
1919
|
:param params: The funding parameters
|
|
1835
1920
|
:param send_params: Send parameters, defaults to None
|
|
1836
1921
|
:return: The transaction result
|
|
1922
|
+
|
|
1923
|
+
:example:
|
|
1924
|
+
>>> result = client.fund_app_account(params)
|
|
1837
1925
|
"""
|
|
1838
1926
|
return self.send.fund_app_account(params, send_params)
|
|
1839
1927
|
|