You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/capabilities/algorand-client.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ The `AlgorandClient` has a number of manager class instances that help you quick
54
54
55
55
### Creating transactions
56
56
57
-
You can compose a transaction via `algorand.createTransaction...`, which gives you an instance of the [`AlgorandClientTransactionCreator`](../code/classes/types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md) class. Intellisense will guide you on the different options.
57
+
You can compose a transaction via `algorand.createTransaction.`, which gives you an instance of the [`AlgorandClientTransactionCreator`](../code/classes/types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md) class. Intellisense will guide you on the different options.
58
58
59
59
The signature for the calls to send a single transaction usually look like:
60
60
@@ -147,8 +147,10 @@ There are two common base interfaces that get reused:
-`maxRoundsToWaitForConfirmation?: number` - The number of rounds to wait for confirmation. By default until the latest lastValid has past.
149
149
-`suppressLog?: boolean` - Whether to suppress log messages from transaction send, default: do not suppress.
150
+
-`populateAppCallResources?: boolean` - Whether to use simulate to automatically populate app call resources in the txn objects. Defaults to `Config.populateAppCallResources`.
151
+
-`coverAppCallInnerTransactionFees?: boolean` - Whether to use simulate to automatically calculate required app call inner transaction fees and cover them in the parent app call transaction fee
150
152
151
-
Then on top of that the base type gets extended for the specific type of transaction you are issuing. These are all defined as part of [`TransactionComposer`](./transaction-composer.md).
153
+
Then on top of that the base type gets extended for the specific type of transaction you are issuing. These are all defined as part of [`TransactionComposer`](./transaction-composer.md) and we recommend reading these docs, especially when leveraging either `populateAppCallResources` or `coverAppCallInnerTransactionFees`.
Copy file name to clipboardExpand all lines: docs/capabilities/testing.md
+53-6Lines changed: 53 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,15 +24,37 @@ import { algorandFixture } from '@algorandfoundation/algokit-utils/testing'
24
24
25
25
### Using with Jest
26
26
27
-
To integrate with [Jest](https://jestjs.io/) you need to pass the `fixture.beforeEach` method into Jest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.
27
+
To integrate with [Jest](https://jestjs.io/) you need to pass the `fixture.newScope` method into Jest's `beforeEach` method (for per test isolation) or `beforeAll` method (for test suite isolation) and then within each test you can access `fixture.context` to access the isolated fixture values.
@@ -46,15 +68,37 @@ Occasionally there may be a delay when first running the fixture setup so we add
46
68
47
69
### Using with vitest
48
70
49
-
To integrate with [vitest](https://vitest.dev/) you need to pass the `fixture.beforeEach` method into vitest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.
71
+
To integrate with [vitest](https://vitest.dev/) you need to pass the `fixture.beforeEach` method into vitest's `beforeEach` method (for per test isolation) or `beforeAll` method (for test suite isolation) and then within each test you can access `fixture.context` to access the isolated fixture values.
Occasionally there may be a delay when first running the fixture setup so we add a 10s timeout to avoid intermittent test failures (`10_000`).
112
+
67
113
### Fixture configuration
68
114
69
115
When calling `algorandFixture()` you can optionally pass in some fixture configuration, with any of these properties (all optional):
@@ -72,6 +118,7 @@ When calling `algorandFixture()` you can optionally pass in some fixture configu
72
118
-`indexer?: Indexer` - An optional indexer client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
73
119
-`kmd?: Kmd` - An optional kmd client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
74
120
-`testAccountFunding?: AlgoAmount` - The [amount](./amount.md) of funds to allocate to the default testing account, if not specified then it will get `10` ALGO
121
+
-`accountGetter?: (algod: Algodv2, kmd?: Kmd) => Promise<Account>` - Optional override for how to get an account; this allows you to retrieve test accounts from a known or cached list of accounts.
75
122
76
123
### Using the fixture context
77
124
@@ -84,7 +131,7 @@ The `fixture.context` property is of type [`AlgorandTestAutomationContext`](../c
84
131
-`transactionLogger: TransactionLogger` - Transaction logger that will log transaction IDs for all transactions issued by `algod`
85
132
-`testAccount: Account` - Funded test account that is ephemerally created for each test
86
133
-`generateAccount: (params: GetTestAccountParams) => Promise<Account>` - Generate and fund an additional ephemerally created account
87
-
-`waitForIndexer: () => Promise<void>` - Wait for the indexer to catch up with all transactions logged by transactionLogger
134
+
-`waitForIndexer()` - Waits for indexer to catch up with the latest transaction that has been captured by the `transactionLogger` in the Algorand fixture
88
135
-`waitForIndexerTransaction: (transactionId: string) => Promise<TransactionLookupResult>` - Wait for the indexer to catch up with the given transaction ID
89
136
90
137
## Log capture fixture
@@ -170,7 +217,7 @@ This means it's easy to create tests that are flaky and have intermittent test f
170
217
The testing capability provides mechanisms for waiting for indexer to catch up, namely:
171
218
172
219
-`algotesting.runWhenIndexerCaughtUp(run: () => Promise<T>)` - Executes the given action every 200ms up to 20 times until there is no longer an error with a `status` property with `404` and then returns the result of the action; this will work for any call that calls indexer APIs expecting to return a single record
173
-
-`algorandFixture.waitForIndexer()` - Waits for indexer to catch up with all transactions that have been captured by the `transactionLogger` in the Algorand fixture
220
+
-`algorandFixture.waitForIndexer()` - Waits for indexer to catch up with the latest transaction that has been captured by the `transactionLogger` in the Algorand fixture
174
221
-`algorandFixture.waitForIndexerTransaction(transactionId)` - Waits for indexer to catch up with the single transaction of the given ID
Once you have constructed all the required transactions, they can be sent by calling `send()` on the `TransactionComposer`.
51
+
Additionally `send()` takes a number of parameters which allow you to opt-in to some additional behaviours as part of sending the transaction or transaction group, mostly significantly `populateAppCallResources` and `coverAppCallInnerTransactionFees`.
52
+
53
+
### Populating App Call Resource
54
+
55
+
`populateAppCallResources` automatically updates the relevant app call transactions in the group to include the account, app, asset and box resources required for the transactions to execute successfully. It leverages the simulate endpoint to discover the accessed resources, which have not been explicitly specified. This setting only applies when you have constucted at least one app call transaction. You can read more about [resources and the reference arrays](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/?from_query=resources#reference-arrays) in the docs.
If `my_method` in the above example accesses any resources, they will be automatically discovered and added before sending the transaction to the network.
75
+
76
+
### Covering App Call Inner Transaction Fees
77
+
78
+
`coverAppCallInnerTransactionFees` automatically calculate the required fee for a parent app call transaction that sends inner transactions. It leverages the simulate endpoint to discover the inner transactions sent and calculates a fee delta to resolve the optimal fee. This feature also takes care of accounting for any surplus transaction fee at the various levels, so as to effectively minimise the fees needed to successfully handle complex scenarios. This setting only applies when you have constucted at least one app call transaction.
maxFee: microAlgo(5000), // NOTE: a maxFee value is required when enabling coverAppCallInnerTransactionFees
92
+
})
93
+
.send({
94
+
coverAppCallInnerTransactionFees: true,
95
+
})
96
+
```
97
+
98
+
Assuming the app account is not covering any of the inner transaction fees, if `my_method` in the above example sends 2 inner transactions, then the fee calculated for the parent transaction will be 3000 µALGO when the transaction is sent to the network.
99
+
100
+
The above example also has a `maxFee` of 5000 µALGO specified. An exception will be thrown if the transaction fee execeeds that value, which allows you to set fee limits. The `maxFee` field is required when enabling `coverAppCallInnerTransactionFees`.
101
+
102
+
Because `maxFee` is required and an `algosdk.Transaction` does not hold any max fee information, you cannot use the generic `addTransaction()` method on the composer with `coverAppCallInnerTransactionFees` enabled. Instead use the below, which provides a better overall experience:
// Note the use of .params. here, this ensure that maxFee is still available to the composer
154
+
const appCallArg =awaitappClient2.params.call({
155
+
method: 'my_other_method',
156
+
args: [],
157
+
maxFee: microAlgo(2000),
158
+
})
159
+
160
+
const result =awaitappClient1.algorand
161
+
.newGroup()
162
+
.addAppCallMethodCall(
163
+
awaitappClient1.params.call({
164
+
method: 'my_method',
165
+
args: [paymentArg, appCallArg],
166
+
maxFee: microAlgo(5000),
167
+
}),
168
+
)
169
+
.send({
170
+
coverAppCallInnerTransactionFees: true,
171
+
})
172
+
```
173
+
174
+
This feature should efficiently calculate the minimum fee needed to execute an app call transaction with inners, however we always recommend testing your specific scenario behaves as expected before releasing.
175
+
176
+
### Covering App Call Op Budget
177
+
178
+
The high level Algorand contract authoring languages all have support for ensuring appropriate app op budget is available via `ensure_budget` in Algorand Python, `ensureBudget` in Algorand TypeScript and `increaseOpcodeBudget` in TEALScript. This is great, as it allows contract authors to ensure appropriate budget is available by automatically sending op-up inner transactions to increase the budget available. These op-up inner transactions require the fees to be covered by an account, which is generally the responsibility of the application consumer.
179
+
180
+
Application consumers may not be immediately aware of the number of op-up inner transactions sent, so it can be difficult for them to determine the exact fees required to successfully execute an application call. Fortunately the `coverAppCallInnerTransactionFees` setting above can be leveraged to automatically cover the fees for any op-up inner transaction that an application sends. Additionally if a contract author decides to cover the fee for an op-up inner transaction, then the application consumer will not be charged a fee for that transaction.
181
+
47
182
## Simulating a transaction
48
183
49
184
Transactions can be simulated using the simulate endpoint in algod, which enables evaluating the transaction on the network without it actually being commited to a block.
Copy file name to clipboardExpand all lines: docs/capabilities/transaction.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,4 +20,4 @@ There are various variations of the `ConfirmedTransactionResult` that are expose
20
20
21
21
## Further reading
22
22
23
-
To understand how to create, simulate and send transactions consult the [`AlgorandClient`](./algorand-client.md) and [`AlgorandClient`](./algokit-composer.md) documentation.
23
+
To understand how to create, simulate and send transactions consult the [`AlgorandClient`](./algorand-client.md) and [`TransactionComposer`](./transaction-composer.md) documentation.
Note: If you are using a version of AlgoKit Utils >= 7.0.0 in your project, you will need to generate using >= 4.0.0. See [AlgoKit CLI generator version pinning](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md#version-pinning) for more information on how to lock to a specific version.
24
+
Note: AlgoKit Utils >= 7.0.0 is compatible with the older 3.0.0 generated typed clients, however if you want to utilise the new features or leverage ARC-56 support, you will need to generate using >= 4.0.0. See [AlgoKit CLI generator version pinning](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md#version-pinning) for more information on how to lock to a specific version.
0 commit comments