@algorandfoundation/algokit-utils 7.0.0-beta.9 → 8.0.0-beta.1
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.
- package/LICENSE +21 -0
- package/README.md +21 -3
- package/account/account.d.ts +4 -1
- package/account/account.js +10 -7
- package/account/account.js.map +1 -1
- package/account/account.mjs +11 -8
- package/account/account.mjs.map +1 -1
- package/account/get-account-config-from-environment.js.map +1 -1
- package/account/get-account-config-from-environment.mjs.map +1 -1
- package/account/get-account.js.map +1 -1
- package/account/get-account.mjs.map +1 -1
- package/account/get-dispenser-account.d.ts +1 -1
- package/account/get-dispenser-account.js.map +1 -1
- package/account/get-dispenser-account.mjs.map +1 -1
- package/account/mnemonic-account.js.map +1 -1
- package/account/mnemonic-account.mjs.map +1 -1
- package/amount.d.ts +1 -0
- package/amount.js +3 -2
- package/amount.js.map +1 -1
- package/amount.mjs +3 -3
- package/amount.mjs.map +1 -1
- package/app-client.d.ts +4 -4
- package/app-client.js +4 -4
- package/app-client.js.map +1 -1
- package/app-client.mjs +4 -4
- package/app-client.mjs.map +1 -1
- package/app-deploy.js +25 -15
- package/app-deploy.js.map +1 -1
- package/app-deploy.mjs +27 -17
- package/app-deploy.mjs.map +1 -1
- package/app.d.ts +2 -2
- package/app.js +9 -6
- package/app.js.map +1 -1
- package/app.mjs +9 -6
- package/app.mjs.map +1 -1
- package/asset.js.map +1 -1
- package/asset.mjs.map +1 -1
- package/debugging/debugging.js.map +1 -1
- package/debugging/debugging.mjs.map +1 -1
- package/dispenser-client.js.map +1 -1
- package/dispenser-client.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +7 -1
- package/index.js.map +1 -1
- package/index.mjs +3 -2
- package/index.mjs.map +1 -1
- package/indexer-lookup.d.ts +10 -8
- package/indexer-lookup.js +14 -10
- package/indexer-lookup.js.map +1 -1
- package/indexer-lookup.mjs +14 -10
- package/indexer-lookup.mjs.map +1 -1
- package/localnet/get-kmd-wallet-account.js.map +1 -1
- package/localnet/get-kmd-wallet-account.mjs.map +1 -1
- package/localnet/get-localnet-dispenser-account.js.map +1 -1
- package/localnet/get-localnet-dispenser-account.mjs.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.js.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.mjs.map +1 -1
- package/localnet/is-localnet.js.map +1 -1
- package/localnet/is-localnet.mjs.map +1 -1
- package/network-client.d.ts +1 -7
- package/network-client.js +2 -9
- package/network-client.js.map +1 -1
- package/network-client.mjs +2 -9
- package/network-client.mjs.map +1 -1
- package/package.json +5 -5
- package/testing/_asset.d.ts +2 -1
- package/testing/account.d.ts +4 -3
- package/testing/account.js +8 -2
- package/testing/account.js.map +1 -1
- package/testing/account.mjs +9 -3
- package/testing/account.mjs.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
- package/testing/fixtures/algorand-fixture.js +5 -6
- package/testing/fixtures/algorand-fixture.js.map +1 -1
- package/testing/fixtures/algorand-fixture.mjs +5 -6
- package/testing/fixtures/algorand-fixture.mjs.map +1 -1
- package/testing/indexer.js.map +1 -1
- package/testing/indexer.mjs.map +1 -1
- package/testing/test-logger.js +7 -1
- package/testing/test-logger.js.map +1 -1
- package/testing/test-logger.mjs +7 -1
- package/testing/test-logger.mjs.map +1 -1
- package/testing/transaction-logger.js.map +1 -1
- package/testing/transaction-logger.mjs.map +1 -1
- package/transaction/legacy-bridge.js +2 -2
- package/transaction/legacy-bridge.js.map +1 -1
- package/transaction/legacy-bridge.mjs +3 -3
- package/transaction/legacy-bridge.mjs.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.d.ts +4 -1
- package/transaction/perform-atomic-transaction-composer-simulate.js +14 -9
- package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.mjs +15 -10
- package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
- package/transaction/transaction.d.ts +13 -22
- package/transaction/transaction.js +164 -110
- package/transaction/transaction.js.map +1 -1
- package/transaction/transaction.mjs +163 -109
- package/transaction/transaction.mjs.map +1 -1
- package/transfer/transfer-algos.js.map +1 -1
- package/transfer/transfer-algos.mjs.map +1 -1
- package/transfer/transfer.js +3 -1
- package/transfer/transfer.js.map +1 -1
- package/transfer/transfer.mjs +3 -1
- package/transfer/transfer.mjs.map +1 -1
- package/types/account-manager.d.ts +20 -20
- package/types/account-manager.js +36 -27
- package/types/account-manager.js.map +1 -1
- package/types/account-manager.mjs +38 -29
- package/types/account-manager.mjs.map +1 -1
- package/types/account.d.ts +17 -8
- package/types/account.js +2 -2
- package/types/account.js.map +1 -1
- package/types/account.mjs +3 -3
- package/types/account.mjs.map +1 -1
- package/types/algo-http-client-with-retry.d.ts +1 -2
- package/types/algo-http-client-with-retry.js +33 -3
- package/types/algo-http-client-with-retry.js.map +1 -1
- package/types/algo-http-client-with-retry.mjs +32 -2
- package/types/algo-http-client-with-retry.mjs.map +1 -1
- package/types/algorand-client-interface.d.ts +2 -2
- package/types/algorand-client-transaction-creator.d.ts +16 -14
- package/types/algorand-client-transaction-creator.js +3 -1
- package/types/algorand-client-transaction-creator.js.map +1 -1
- package/types/algorand-client-transaction-creator.mjs +3 -1
- package/types/algorand-client-transaction-creator.mjs.map +1 -1
- package/types/algorand-client-transaction-sender.d.ts +109 -105
- package/types/algorand-client-transaction-sender.js +6 -2
- package/types/algorand-client-transaction-sender.js.map +1 -1
- package/types/algorand-client-transaction-sender.mjs +6 -2
- package/types/algorand-client-transaction-sender.mjs.map +1 -1
- package/types/algorand-client.d.ts +6 -7
- package/types/algorand-client.js +3 -6
- package/types/algorand-client.js.map +1 -1
- package/types/algorand-client.mjs +5 -5
- package/types/algorand-client.mjs.map +1 -1
- package/types/amount.js.map +1 -1
- package/types/amount.mjs.map +1 -1
- package/types/app-arc56.d.ts +31 -20
- package/types/app-arc56.js.map +1 -1
- package/types/app-arc56.mjs.map +1 -1
- package/types/app-client.d.ts +298 -286
- package/types/app-client.js +148 -41
- package/types/app-client.js.map +1 -1
- package/types/app-client.mjs +147 -40
- package/types/app-client.mjs.map +1 -1
- package/types/app-deployer.d.ts +4 -4
- package/types/app-deployer.js +23 -24
- package/types/app-deployer.js.map +1 -1
- package/types/app-deployer.mjs +25 -26
- package/types/app-deployer.mjs.map +1 -1
- package/types/app-factory.d.ts +130 -130
- package/types/app-factory.js +4 -5
- package/types/app-factory.js.map +1 -1
- package/types/app-factory.mjs +5 -6
- package/types/app-factory.mjs.map +1 -1
- package/types/app-manager.d.ts +5 -5
- package/types/app-manager.js +116 -38
- package/types/app-manager.js.map +1 -1
- package/types/app-manager.mjs +117 -39
- package/types/app-manager.mjs.map +1 -1
- package/types/app-spec.js +8 -2
- package/types/app-spec.js.map +1 -1
- package/types/app-spec.mjs +8 -2
- package/types/app-spec.mjs.map +1 -1
- package/types/app.d.ts +12 -11
- package/types/app.js.map +1 -1
- package/types/app.mjs.map +1 -1
- package/types/asset-manager.d.ts +9 -9
- package/types/asset-manager.js +10 -13
- package/types/asset-manager.js.map +1 -1
- package/types/asset-manager.mjs +10 -13
- package/types/asset-manager.mjs.map +1 -1
- package/types/async-event-emitter.d.ts +1 -10
- package/types/async-event-emitter.js +0 -5
- package/types/async-event-emitter.js.map +1 -1
- package/types/async-event-emitter.mjs +1 -6
- package/types/async-event-emitter.mjs.map +1 -1
- package/types/client-manager.d.ts +2 -9
- package/types/client-manager.js +11 -21
- package/types/client-manager.js.map +1 -1
- package/types/client-manager.mjs +11 -21
- package/types/client-manager.mjs.map +1 -1
- package/types/composer.d.ts +58 -46
- package/types/composer.js +154 -105
- package/types/composer.js.map +1 -1
- package/types/composer.mjs +156 -105
- package/types/composer.mjs.map +1 -1
- package/types/config.js.map +1 -1
- package/types/config.mjs.map +1 -1
- package/types/debugging.d.ts +1 -1
- package/types/debugging.js +1 -1
- package/types/debugging.js.map +1 -1
- package/types/debugging.mjs +1 -1
- package/types/debugging.mjs.map +1 -1
- package/types/dispenser-client.d.ts +2 -1
- package/types/dispenser-client.js +5 -1
- package/types/dispenser-client.js.map +1 -1
- package/types/dispenser-client.mjs +5 -1
- package/types/dispenser-client.mjs.map +1 -1
- package/types/indexer.d.ts +74 -755
- package/types/indexer.js.map +1 -1
- package/types/indexer.mjs.map +1 -1
- package/types/kmd-account-manager.d.ts +2 -2
- package/types/kmd-account-manager.js +1 -1
- package/types/kmd-account-manager.js.map +1 -1
- package/types/kmd-account-manager.mjs +2 -2
- package/types/kmd-account-manager.mjs.map +1 -1
- package/types/lifecycle-events.d.ts +10 -0
- package/types/lifecycle-events.js +8 -0
- package/types/lifecycle-events.js.map +1 -0
- package/types/lifecycle-events.mjs +8 -0
- package/types/lifecycle-events.mjs.map +1 -0
- package/types/logging.js.map +1 -1
- package/types/logging.mjs.map +1 -1
- package/types/logic-error.d.ts +2 -3
- package/types/logic-error.js +3 -3
- package/types/logic-error.js.map +1 -1
- package/types/logic-error.mjs +3 -3
- package/types/logic-error.mjs.map +1 -1
- package/types/network-client.d.ts +1 -1
- package/types/network-client.js.map +1 -1
- package/types/network-client.mjs.map +1 -1
- package/types/testing.d.ts +6 -7
- package/util.js.map +1 -1
- package/util.mjs.map +1 -1
- package/types/urlTokenBaseHTTPClient.d.ts +0 -40
- package/types/urlTokenBaseHTTPClient.js +0 -153
- package/types/urlTokenBaseHTTPClient.js.map +0 -1
- package/types/urlTokenBaseHTTPClient.mjs +0 -151
- package/types/urlTokenBaseHTTPClient.mjs.map +0 -1
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import algosdk from 'algosdk';
|
|
1
|
+
import algosdk, { TransactionType, stringifyJSON, Address } from 'algosdk';
|
|
2
2
|
import { Buffer } from 'buffer';
|
|
3
3
|
import { Config } from '../config.mjs';
|
|
4
|
-
import { EventType } from '../types/
|
|
4
|
+
import { EventType } from '../types/lifecycle-events.mjs';
|
|
5
5
|
import { toNumber } from '../util.mjs';
|
|
6
6
|
import { performAtomicTransactionComposerSimulate } from './perform-atomic-transaction-composer-simulate.mjs';
|
|
7
7
|
|
|
8
8
|
var AtomicTransactionComposer = algosdk.AtomicTransactionComposer;
|
|
9
|
-
var modelsv2 = algosdk.modelsv2;
|
|
10
9
|
const MAX_TRANSACTION_GROUP_SIZE = 16;
|
|
11
10
|
const MAX_APP_CALL_FOREIGN_REFERENCES = 8;
|
|
12
11
|
const MAX_APP_CALL_ACCOUNT_REFERENCES = 4;
|
|
13
12
|
/**
|
|
14
|
-
* @deprecated Convert your data to a `string` or `Uint8Array`, if using ARC-2 use `
|
|
13
|
+
* @deprecated Convert your data to a `string` or `Uint8Array`, if using ARC-2 use `TransactionComposer.arc2Note`.
|
|
15
14
|
*
|
|
16
15
|
* Encodes a transaction note into a byte array ready to be included in an Algorand transaction.
|
|
17
16
|
*
|
|
@@ -87,10 +86,10 @@ function encodeLease(lease) {
|
|
|
87
86
|
* @returns The public address
|
|
88
87
|
*/
|
|
89
88
|
const getSenderAddress = function (sender) {
|
|
90
|
-
return typeof sender === 'string' ? sender : 'addr' in sender ? sender.addr : sender.address();
|
|
89
|
+
return typeof sender === 'string' ? sender : 'addr' in sender ? sender.addr.toString() : sender.address().toString();
|
|
91
90
|
};
|
|
92
91
|
/**
|
|
93
|
-
* @deprecated Use `AlgorandClient` / `
|
|
92
|
+
* @deprecated Use `AlgorandClient` / `TransactionComposer` to construct transactions instead or
|
|
94
93
|
* construct an `algosdk.TransactionWithSigner` manually instead.
|
|
95
94
|
*
|
|
96
95
|
* Given a transaction in a variety of supported formats, returns a TransactionWithSigner object ready to be passed to an
|
|
@@ -147,7 +146,7 @@ const getSenderTransactionSigner = memoize(function (sender) {
|
|
|
147
146
|
: algosdk.makeBasicAccountTransactionSigner(sender);
|
|
148
147
|
});
|
|
149
148
|
/**
|
|
150
|
-
* @deprecated Use `AlgorandClient` / `
|
|
149
|
+
* @deprecated Use `AlgorandClient` / `TransactionComposer` to sign transactions
|
|
151
150
|
* or use the relevant underlying `account.signTxn` / `algosdk.signLogicSigTransactionObject`
|
|
152
151
|
* / `multiSigAccount.sign` / `TransactionSigner` methods directly.
|
|
153
152
|
*
|
|
@@ -166,7 +165,7 @@ const signTransaction = async (transaction, signer) => {
|
|
|
166
165
|
: (await signer.signer([transaction], [0]))[0];
|
|
167
166
|
};
|
|
168
167
|
/**
|
|
169
|
-
* @deprecated Use `AlgorandClient` / `
|
|
168
|
+
* @deprecated Use `AlgorandClient` / `TransactionComposer` to send transactions.
|
|
170
169
|
*
|
|
171
170
|
* Prepares a transaction for sending and then (if instructed) signs and sends the given transaction to the chain.
|
|
172
171
|
*
|
|
@@ -216,29 +215,18 @@ const sendTransaction = async function (send, algod) {
|
|
|
216
215
|
* @returns The unnamed resources accessed by the group and by each transaction in the group
|
|
217
216
|
*/
|
|
218
217
|
async function getUnnamedAppCallResourcesAccessed(atc, algod) {
|
|
219
|
-
const
|
|
218
|
+
const simulateRequest = new algosdk.modelsv2.SimulateRequest({
|
|
220
219
|
txnGroups: [],
|
|
221
220
|
allowUnnamedResources: true,
|
|
222
221
|
allowEmptySignatures: true,
|
|
222
|
+
fixSigners: true,
|
|
223
223
|
});
|
|
224
|
-
const
|
|
225
|
-
const stxns = await algosdk.makeEmptyTransactionSigner()(txns, indexes);
|
|
226
|
-
return Promise.all(stxns.map(async (stxn) => {
|
|
227
|
-
const decodedStxn = algosdk.decodeSignedTransaction(stxn);
|
|
228
|
-
const sender = algosdk.encodeAddress(decodedStxn.txn.from.publicKey);
|
|
229
|
-
const authAddr = (await algod.accountInformation(sender).do())['auth-addr'];
|
|
230
|
-
const stxnObj = { txn: decodedStxn.txn.get_obj_for_encoding() };
|
|
231
|
-
if (authAddr !== undefined) {
|
|
232
|
-
stxnObj.sgnr = Buffer.from(algosdk.decodeAddress(authAddr).publicKey);
|
|
233
|
-
}
|
|
234
|
-
return algosdk.encodeObj(stxnObj);
|
|
235
|
-
}));
|
|
236
|
-
};
|
|
224
|
+
const nullSigner = algosdk.makeEmptyTransactionSigner();
|
|
237
225
|
const emptySignerAtc = atc.clone();
|
|
238
226
|
emptySignerAtc['transactions'].forEach((t) => {
|
|
239
|
-
t.signer =
|
|
227
|
+
t.signer = nullSigner;
|
|
240
228
|
});
|
|
241
|
-
const result = await emptySignerAtc.simulate(algod,
|
|
229
|
+
const result = await emptySignerAtc.simulate(algod, simulateRequest);
|
|
242
230
|
const groupResponse = result.simulateResponse.txnGroups[0];
|
|
243
231
|
if (groupResponse.failureMessage) {
|
|
244
232
|
throw Error(`Error during resource population simulation in transaction ${groupResponse.failedAt}: ${groupResponse.failureMessage}`);
|
|
@@ -271,7 +259,7 @@ async function populateAppCallResources(atc, algod) {
|
|
|
271
259
|
const unnamedResourcesAccessed = await getUnnamedAppCallResourcesAccessed(atc, algod);
|
|
272
260
|
const group = atc.buildGroup();
|
|
273
261
|
unnamedResourcesAccessed.txns.forEach((r, i) => {
|
|
274
|
-
if (r === undefined)
|
|
262
|
+
if (r === undefined || group[i].txn.type !== TransactionType.appl)
|
|
275
263
|
return;
|
|
276
264
|
if (r.boxes || r.extraBoxRefs)
|
|
277
265
|
throw Error('Unexpected boxes at the transaction level');
|
|
@@ -279,22 +267,19 @@ async function populateAppCallResources(atc, algod) {
|
|
|
279
267
|
throw Error('Unexpected app local at the transaction level');
|
|
280
268
|
if (r.assetHoldings)
|
|
281
269
|
throw Error('Unexpected asset holding at the transaction level');
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
group[i].txn.appForeignAssets = [...(group[i].txn.appForeignAssets ?? []), Number(a)];
|
|
291
|
-
});
|
|
292
|
-
const accounts = group[i].txn.appAccounts?.length || 0;
|
|
270
|
+
group[i].txn['applicationCall'] = {
|
|
271
|
+
...group[i].txn.applicationCall,
|
|
272
|
+
accounts: [...(group[i].txn?.applicationCall?.accounts ?? []), ...(r.accounts ?? [])],
|
|
273
|
+
foreignApps: [...(group[i].txn?.applicationCall?.foreignApps ?? []), ...(r.apps ?? [])],
|
|
274
|
+
foreignAssets: [...(group[i].txn?.applicationCall?.foreignAssets ?? []), ...(r.assets ?? [])],
|
|
275
|
+
boxes: [...(group[i].txn?.applicationCall?.boxes ?? []), ...(r.boxes ?? [])],
|
|
276
|
+
};
|
|
277
|
+
const accounts = group[i].txn.applicationCall?.accounts?.length ?? 0;
|
|
293
278
|
if (accounts > MAX_APP_CALL_ACCOUNT_REFERENCES)
|
|
294
279
|
throw Error(`Account reference limit of ${MAX_APP_CALL_ACCOUNT_REFERENCES} exceeded in transaction ${i}`);
|
|
295
|
-
const assets = group[i].txn.
|
|
296
|
-
const apps = group[i].txn.
|
|
297
|
-
const boxes = group[i].txn.boxes?.length
|
|
280
|
+
const assets = group[i].txn.applicationCall?.foreignAssets?.length ?? 0;
|
|
281
|
+
const apps = group[i].txn.applicationCall?.foreignApps?.length ?? 0;
|
|
282
|
+
const boxes = group[i].txn.applicationCall?.boxes?.length ?? 0;
|
|
298
283
|
if (accounts + assets + apps + boxes > MAX_APP_CALL_FOREIGN_REFERENCES) {
|
|
299
284
|
throw Error(`Resource reference limit of ${MAX_APP_CALL_FOREIGN_REFERENCES} exceeded in transaction ${i}`);
|
|
300
285
|
}
|
|
@@ -303,10 +288,10 @@ async function populateAppCallResources(atc, algod) {
|
|
|
303
288
|
const isApplBelowLimit = (t) => {
|
|
304
289
|
if (t.txn.type !== algosdk.TransactionType.appl)
|
|
305
290
|
return false;
|
|
306
|
-
const accounts = t.txn.
|
|
307
|
-
const assets = t.txn.
|
|
308
|
-
const apps = t.txn.
|
|
309
|
-
const boxes = t.txn.boxes?.length
|
|
291
|
+
const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
|
|
292
|
+
const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
|
|
293
|
+
const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
|
|
294
|
+
const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
|
|
310
295
|
return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES;
|
|
311
296
|
};
|
|
312
297
|
// If this is a asset holding or app local, first try to find a transaction that already has the account available
|
|
@@ -317,22 +302,26 @@ async function populateAppCallResources(atc, algod) {
|
|
|
317
302
|
return false;
|
|
318
303
|
return (
|
|
319
304
|
// account is in the foreign accounts array
|
|
320
|
-
t.txn.
|
|
305
|
+
t.txn.applicationCall?.accounts?.map((a) => a.toString()).includes(account.toString()) ||
|
|
321
306
|
// account is available as an app account
|
|
322
|
-
t.txn.
|
|
307
|
+
t.txn.applicationCall?.foreignApps?.map((a) => algosdk.getApplicationAddress(a).toString()).includes(account.toString()) ||
|
|
323
308
|
// account is available since it's in one of the fields
|
|
324
|
-
Object.values(t.txn)
|
|
325
|
-
.map((f) => JSON.stringify(f))
|
|
326
|
-
.includes(JSON.stringify(algosdk.decodeAddress(account))));
|
|
309
|
+
Object.values(t.txn).some((f) => stringifyJSON(f, (_, v) => (v instanceof Address ? v.toString() : v))?.includes(account.toString())));
|
|
327
310
|
});
|
|
328
311
|
if (txnIndex > -1) {
|
|
329
312
|
if (type === 'assetHolding') {
|
|
330
313
|
const { asset } = reference;
|
|
331
|
-
txns[txnIndex].txn
|
|
314
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
315
|
+
...txns[txnIndex].txn.applicationCall,
|
|
316
|
+
foreignAssets: [...(txns[txnIndex].txn?.applicationCall?.foreignAssets ?? []), ...[asset]],
|
|
317
|
+
};
|
|
332
318
|
}
|
|
333
319
|
else {
|
|
334
320
|
const { app } = reference;
|
|
335
|
-
txns[txnIndex].txn
|
|
321
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
322
|
+
...txns[txnIndex].txn.applicationCall,
|
|
323
|
+
foreignApps: [...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []), ...[app]],
|
|
324
|
+
};
|
|
336
325
|
}
|
|
337
326
|
return;
|
|
338
327
|
}
|
|
@@ -341,20 +330,23 @@ async function populateAppCallResources(atc, algod) {
|
|
|
341
330
|
if (!isApplBelowLimit(t))
|
|
342
331
|
return false;
|
|
343
332
|
// check if there is space in the accounts array
|
|
344
|
-
if ((t.txn.
|
|
333
|
+
if ((t.txn.applicationCall?.accounts?.length ?? 0) >= MAX_APP_CALL_ACCOUNT_REFERENCES)
|
|
345
334
|
return false;
|
|
346
335
|
if (type === 'assetHolding') {
|
|
347
336
|
const { asset } = reference;
|
|
348
|
-
return t.txn.
|
|
337
|
+
return t.txn.applicationCall?.foreignAssets?.includes(asset);
|
|
349
338
|
}
|
|
350
339
|
else {
|
|
351
340
|
const { app } = reference;
|
|
352
|
-
return t.txn.
|
|
341
|
+
return t.txn.applicationCall?.foreignApps?.includes(app) || t.txn.applicationCall?.appIndex === app;
|
|
353
342
|
}
|
|
354
343
|
});
|
|
355
344
|
if (txnIndex > -1) {
|
|
356
345
|
const { account } = reference;
|
|
357
|
-
txns[txnIndex].txn
|
|
346
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
347
|
+
...txns[txnIndex].txn.applicationCall,
|
|
348
|
+
accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[account]],
|
|
349
|
+
};
|
|
358
350
|
return;
|
|
359
351
|
}
|
|
360
352
|
}
|
|
@@ -365,10 +357,13 @@ async function populateAppCallResources(atc, algod) {
|
|
|
365
357
|
if (!isApplBelowLimit(t))
|
|
366
358
|
return false;
|
|
367
359
|
// If the app is in the foreign array OR the app being called, then we know it's available
|
|
368
|
-
return t.txn.
|
|
360
|
+
return t.txn.applicationCall?.foreignApps?.includes(app) || t.txn.applicationCall?.appIndex === app;
|
|
369
361
|
});
|
|
370
362
|
if (txnIndex > -1) {
|
|
371
|
-
txns[txnIndex].txn
|
|
363
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
364
|
+
...txns[txnIndex].txn.applicationCall,
|
|
365
|
+
boxes: [...(txns[txnIndex].txn?.applicationCall?.boxes ?? []), ...[{ appIndex: app, name }]],
|
|
366
|
+
};
|
|
372
367
|
return;
|
|
373
368
|
}
|
|
374
369
|
}
|
|
@@ -376,12 +371,12 @@ async function populateAppCallResources(atc, algod) {
|
|
|
376
371
|
const txnIndex = txns.findIndex((t) => {
|
|
377
372
|
if (t.txn.type !== algosdk.TransactionType.appl)
|
|
378
373
|
return false;
|
|
379
|
-
const accounts = t.txn.
|
|
374
|
+
const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
|
|
380
375
|
if (type === 'account')
|
|
381
376
|
return accounts < MAX_APP_CALL_ACCOUNT_REFERENCES;
|
|
382
|
-
const assets = t.txn.
|
|
383
|
-
const apps = t.txn.
|
|
384
|
-
const boxes = t.txn.boxes?.length
|
|
377
|
+
const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
|
|
378
|
+
const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
|
|
379
|
+
const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
|
|
385
380
|
// If we're adding local state or asset holding, we need space for the acocunt and the other reference
|
|
386
381
|
if (type === 'assetHolding' || type === 'appLocal') {
|
|
387
382
|
return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES - 1 && accounts < MAX_APP_CALL_ACCOUNT_REFERENCES;
|
|
@@ -396,30 +391,57 @@ async function populateAppCallResources(atc, algod) {
|
|
|
396
391
|
throw Error('No more transactions below reference limit. Add another app call to the group.');
|
|
397
392
|
}
|
|
398
393
|
if (type === 'account') {
|
|
399
|
-
txns[txnIndex].txn
|
|
394
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
395
|
+
...txns[txnIndex].txn.applicationCall,
|
|
396
|
+
accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[reference]],
|
|
397
|
+
};
|
|
400
398
|
}
|
|
401
399
|
else if (type === 'app') {
|
|
402
|
-
txns[txnIndex].txn
|
|
400
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
401
|
+
...txns[txnIndex].txn.applicationCall,
|
|
402
|
+
foreignApps: [
|
|
403
|
+
...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []),
|
|
404
|
+
...[typeof reference === 'bigint' ? reference : BigInt(reference)],
|
|
405
|
+
],
|
|
406
|
+
};
|
|
403
407
|
}
|
|
404
408
|
else if (type === 'box') {
|
|
405
409
|
const { app, name } = reference;
|
|
406
|
-
txns[txnIndex].txn
|
|
410
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
411
|
+
...txns[txnIndex].txn.applicationCall,
|
|
412
|
+
boxes: [...(txns[txnIndex].txn?.applicationCall?.boxes ?? []), ...[{ appIndex: app, name }]],
|
|
413
|
+
};
|
|
407
414
|
if (app.toString() !== '0') {
|
|
408
|
-
txns[txnIndex].txn
|
|
415
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
416
|
+
...txns[txnIndex].txn.applicationCall,
|
|
417
|
+
foreignApps: [...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []), ...[app]],
|
|
418
|
+
};
|
|
409
419
|
}
|
|
410
420
|
}
|
|
411
421
|
else if (type === 'assetHolding') {
|
|
412
422
|
const { asset, account } = reference;
|
|
413
|
-
txns[txnIndex].txn
|
|
414
|
-
|
|
423
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
424
|
+
...txns[txnIndex].txn.applicationCall,
|
|
425
|
+
foreignAssets: [...(txns[txnIndex].txn?.applicationCall?.foreignAssets ?? []), ...[asset]],
|
|
426
|
+
accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[account]],
|
|
427
|
+
};
|
|
415
428
|
}
|
|
416
429
|
else if (type === 'appLocal') {
|
|
417
430
|
const { app, account } = reference;
|
|
418
|
-
txns[txnIndex].txn
|
|
419
|
-
|
|
431
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
432
|
+
...txns[txnIndex].txn.applicationCall,
|
|
433
|
+
foreignApps: [...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []), ...[app]],
|
|
434
|
+
accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[account]],
|
|
435
|
+
};
|
|
420
436
|
}
|
|
421
437
|
else if (type === 'asset') {
|
|
422
|
-
txns[txnIndex].txn
|
|
438
|
+
txns[txnIndex].txn['applicationCall'] = {
|
|
439
|
+
...txns[txnIndex].txn.applicationCall,
|
|
440
|
+
foreignAssets: [
|
|
441
|
+
...(txns[txnIndex].txn?.applicationCall?.foreignAssets ?? []),
|
|
442
|
+
...[typeof reference === 'bigint' ? reference : BigInt(reference)],
|
|
443
|
+
],
|
|
444
|
+
};
|
|
423
445
|
}
|
|
424
446
|
};
|
|
425
447
|
const g = unnamedResourcesAccessed.group;
|
|
@@ -478,20 +500,14 @@ async function populateAppCallResources(atc, algod) {
|
|
|
478
500
|
const sendAtomicTransactionComposer = async function (atcSend, algod) {
|
|
479
501
|
const { atc: givenAtc, sendParams, ...executeParams } = atcSend;
|
|
480
502
|
let atc;
|
|
481
|
-
// const hasAppCalls = () =>
|
|
482
|
-
// givenAtc
|
|
483
|
-
// .buildGroup()
|
|
484
|
-
// .map((t) => t.txn.type)
|
|
485
|
-
// .includes(algosdk.TransactionType.appl)
|
|
486
503
|
atc = givenAtc;
|
|
487
504
|
try {
|
|
505
|
+
const transactionsWithSigner = atc.buildGroup();
|
|
488
506
|
// If populateAppCallResources is true OR if populateAppCallResources is undefined and there are app calls, then populate resources
|
|
489
|
-
// NOTE: Temporary false by default until this algod bug is fixed: https://github.com/algorand/go-algorand/issues/5914
|
|
490
507
|
const populateResources = executeParams?.populateAppCallResources ?? sendParams?.populateAppCallResources ?? Config.populateAppCallResources;
|
|
491
|
-
if (populateResources) {
|
|
508
|
+
if (populateResources && transactionsWithSigner.map((t) => t.txn.type).includes(algosdk.TransactionType.appl)) {
|
|
492
509
|
atc = await populateAppCallResources(givenAtc, algod);
|
|
493
510
|
}
|
|
494
|
-
const transactionsWithSigner = atc.buildGroup();
|
|
495
511
|
const transactionsToSend = transactionsWithSigner.map((t) => {
|
|
496
512
|
return t.txn;
|
|
497
513
|
});
|
|
@@ -515,22 +531,18 @@ const sendAtomicTransactionComposer = async function (atcSend, algod) {
|
|
|
515
531
|
Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Group transaction (${groupId}) sent with ${transactionsToSend.length} transactions`);
|
|
516
532
|
}
|
|
517
533
|
else {
|
|
518
|
-
Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Sent transaction ID ${transactionsToSend[0].txID()} ${transactionsToSend[0].type} from ${
|
|
534
|
+
Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Sent transaction ID ${transactionsToSend[0].txID()} ${transactionsToSend[0].type} from ${transactionsToSend[0].sender.toString()}`);
|
|
519
535
|
}
|
|
520
536
|
let confirmations = undefined;
|
|
521
537
|
if (!sendParams?.skipWaiting) {
|
|
522
|
-
confirmations = await Promise.all(transactionsToSend.map(async (t) =>
|
|
538
|
+
confirmations = await Promise.all(transactionsToSend.map(async (t) => await algod.pendingTransactionInformation(t.txID()).do()));
|
|
523
539
|
}
|
|
524
540
|
return {
|
|
525
541
|
groupId,
|
|
526
542
|
confirmations,
|
|
527
543
|
txIds: transactionsToSend.map((t) => t.txID()),
|
|
528
544
|
transactions: transactionsToSend,
|
|
529
|
-
returns: result.methodResults.map(
|
|
530
|
-
decodeError: r.decodeError,
|
|
531
|
-
returnValue: r.returnValue,
|
|
532
|
-
rawReturnValue: r.rawReturnValue,
|
|
533
|
-
})),
|
|
545
|
+
returns: result.methodResults.map(getABIReturnValue),
|
|
534
546
|
};
|
|
535
547
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
536
548
|
}
|
|
@@ -543,6 +555,9 @@ const sendAtomicTransactionComposer = async function (atcSend, algod) {
|
|
|
543
555
|
// Remove headers as it doesn't have anything useful.
|
|
544
556
|
delete e.response?.headers;
|
|
545
557
|
err.response = e.response;
|
|
558
|
+
// body property very noisy
|
|
559
|
+
if (e.response && 'body' in e.response)
|
|
560
|
+
delete err.response.body;
|
|
546
561
|
err.name = e.name;
|
|
547
562
|
}
|
|
548
563
|
if (Config.debug && typeof e === 'object') {
|
|
@@ -550,6 +565,7 @@ const sendAtomicTransactionComposer = async function (atcSend, algod) {
|
|
|
550
565
|
Config.logger.error('Received error executing Atomic Transaction Composer and debug flag enabled; attempting simulation to get more information', err);
|
|
551
566
|
const simulate = await performAtomicTransactionComposerSimulate(atc, algod);
|
|
552
567
|
if (Config.debug && !Config.traceAll) {
|
|
568
|
+
// Emit the event only if traceAll: false, as it should have already been emitted above
|
|
553
569
|
await Config.events.emitAsync(EventType.TxnGroupSimulated, {
|
|
554
570
|
simulateResponse: simulate,
|
|
555
571
|
});
|
|
@@ -557,7 +573,7 @@ const sendAtomicTransactionComposer = async function (atcSend, algod) {
|
|
|
557
573
|
if (simulate && simulate.txnGroups[0].failedAt) {
|
|
558
574
|
for (const txn of simulate.txnGroups[0].txnResults) {
|
|
559
575
|
err.traces.push({
|
|
560
|
-
trace: txn.execTrace?.
|
|
576
|
+
trace: txn.execTrace?.toEncodingData(),
|
|
561
577
|
appBudget: txn.appBudgetConsumed,
|
|
562
578
|
logicSigBudget: txn.logicSigBudgetConsumed,
|
|
563
579
|
logs: txn.txnResult.logs,
|
|
@@ -572,24 +588,47 @@ const sendAtomicTransactionComposer = async function (atcSend, algod) {
|
|
|
572
588
|
throw err;
|
|
573
589
|
}
|
|
574
590
|
};
|
|
591
|
+
const convertABIDecodedBigIntToNumber = (value, type) => {
|
|
592
|
+
if (typeof value === 'bigint') {
|
|
593
|
+
if (type instanceof algosdk.ABIUintType) {
|
|
594
|
+
return type.bitSize < 53 ? Number(value) : value;
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
return value;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
else if (Array.isArray(value) && (type instanceof algosdk.ABIArrayStaticType || type instanceof algosdk.ABIArrayDynamicType)) {
|
|
601
|
+
return value.map((v) => convertABIDecodedBigIntToNumber(v, type.childType));
|
|
602
|
+
}
|
|
603
|
+
else if (Array.isArray(value) && type instanceof algosdk.ABITupleType) {
|
|
604
|
+
return value.map((v, i) => convertABIDecodedBigIntToNumber(v, type.childTypes[i]));
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
return value;
|
|
608
|
+
}
|
|
609
|
+
};
|
|
575
610
|
/**
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
* @param atc The AtomicTransactionComposer` with transaction(s) loaded
|
|
580
|
-
* @param algod An Algod client
|
|
581
|
-
* @returns The dryrun result
|
|
611
|
+
* Takes an algosdk `ABIResult` and converts it to an `ABIReturn`.
|
|
612
|
+
* Converts `bigint`'s for Uint's < 64 to `number` for easier use.
|
|
613
|
+
* @param result The `ABIReturn`
|
|
582
614
|
*/
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return
|
|
615
|
+
function getABIReturnValue(result) {
|
|
616
|
+
if (result.decodeError) {
|
|
617
|
+
return {
|
|
618
|
+
decodeError: result.decodeError,
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
method: result.method,
|
|
623
|
+
rawReturnValue: result.rawReturnValue,
|
|
624
|
+
decodeError: undefined,
|
|
625
|
+
returnValue: result.returnValue !== undefined && result.method.returns.type !== 'void'
|
|
626
|
+
? convertABIDecodedBigIntToNumber(result.returnValue, result.method.returns.type)
|
|
627
|
+
: result.returnValue,
|
|
628
|
+
};
|
|
590
629
|
}
|
|
591
630
|
/**
|
|
592
|
-
* @deprecated Use `
|
|
631
|
+
* @deprecated Use `TransactionComposer` (`algorand.newGroup()`) or `AtomicTransactionComposer` to construct and send group transactions instead.
|
|
593
632
|
*
|
|
594
633
|
* Signs and sends a group of [up to 16](https://developer.algorand.org/docs/get-details/atomic_transfers/#create-transactions) transactions to the chain
|
|
595
634
|
*
|
|
@@ -640,7 +679,7 @@ const waitForConfirmation = async function (transactionId, maxRoundsToWait, algo
|
|
|
640
679
|
throw new Error(`Invalid timeout, received ${maxRoundsToWait}, expected > 0`);
|
|
641
680
|
}
|
|
642
681
|
// Get current round
|
|
643
|
-
const status =
|
|
682
|
+
const status = await algod.status().do();
|
|
644
683
|
if (status === undefined) {
|
|
645
684
|
throw new Error('Unable to get node status');
|
|
646
685
|
}
|
|
@@ -649,7 +688,7 @@ const waitForConfirmation = async function (transactionId, maxRoundsToWait, algo
|
|
|
649
688
|
let currentRound = startRound;
|
|
650
689
|
while (currentRound < startRound + BigInt(maxRoundsToWait)) {
|
|
651
690
|
try {
|
|
652
|
-
const pendingInfo =
|
|
691
|
+
const pendingInfo = await algod.pendingTransactionInformation(transactionId).do();
|
|
653
692
|
if (pendingInfo !== undefined) {
|
|
654
693
|
const confirmedRound = pendingInfo.confirmedRound;
|
|
655
694
|
if (confirmedRound && confirmedRound > 0) {
|
|
@@ -677,7 +716,7 @@ const waitForConfirmation = async function (transactionId, maxRoundsToWait, algo
|
|
|
677
716
|
throw new Error(`Transaction ${transactionId} not confirmed after ${maxRoundsToWait} rounds`);
|
|
678
717
|
};
|
|
679
718
|
/**
|
|
680
|
-
* @deprecated Use `
|
|
719
|
+
* @deprecated Use `TransactionComposer` and the `maxFee` field in the transaction params instead.
|
|
681
720
|
*
|
|
682
721
|
* Limit the acceptable fee to a defined amount of µAlgo.
|
|
683
722
|
* This also sets the transaction to be flatFee to ensure the transaction only succeeds at
|
|
@@ -687,21 +726,23 @@ const waitForConfirmation = async function (transactionId, maxRoundsToWait, algo
|
|
|
687
726
|
*/
|
|
688
727
|
function capTransactionFee(transaction, maxAcceptableFee) {
|
|
689
728
|
// If a flat fee hasn't already been defined
|
|
690
|
-
if (!transaction.flatFee) {
|
|
729
|
+
if (!('flatFee' in transaction) || !transaction.flatFee) {
|
|
691
730
|
// Once a transaction has been constructed by algosdk, transaction.fee indicates what the total transaction fee
|
|
692
731
|
// Will be based on the current suggested fee-per-byte value.
|
|
693
732
|
if (transaction.fee > maxAcceptableFee.microAlgo) {
|
|
694
733
|
throw new Error(`Cancelled transaction due to high network congestion fees. Algorand suggested fees would cause this transaction to cost ${transaction.fee} µALGO. Cap for this transaction is ${maxAcceptableFee.microAlgo} µALGO.`);
|
|
695
734
|
}
|
|
696
|
-
else if (transaction.fee >
|
|
735
|
+
else if (transaction.fee > 1000000) {
|
|
697
736
|
Config.logger.warn(`Algorand network congestion fees are in effect. This transaction will incur a fee of ${transaction.fee} µALGO.`);
|
|
698
737
|
}
|
|
699
738
|
// Now set the flat on the transaction. Otherwise the network may increase the fee above our cap and perform the transaction.
|
|
700
|
-
|
|
739
|
+
if ('flatFee' in transaction) {
|
|
740
|
+
transaction.flatFee = true;
|
|
741
|
+
}
|
|
701
742
|
}
|
|
702
743
|
}
|
|
703
744
|
/**
|
|
704
|
-
* @deprecated Use `
|
|
745
|
+
* @deprecated Use `TransactionComposer` and the `maxFee` and `staticFee` fields in the transaction params instead.
|
|
705
746
|
*
|
|
706
747
|
* Allows for control of fees on a `Transaction` or `SuggestedParams` object
|
|
707
748
|
* @param transaction The transaction or suggested params
|
|
@@ -711,7 +752,9 @@ function controlFees(transaction, feeControl) {
|
|
|
711
752
|
const { fee, maxFee } = feeControl;
|
|
712
753
|
if (fee) {
|
|
713
754
|
transaction.fee = Number(fee.microAlgo);
|
|
714
|
-
|
|
755
|
+
if ('flatFee' in transaction) {
|
|
756
|
+
transaction.flatFee = true;
|
|
757
|
+
}
|
|
715
758
|
}
|
|
716
759
|
if (maxFee !== undefined) {
|
|
717
760
|
capTransactionFee(transaction, maxFee);
|
|
@@ -727,7 +770,18 @@ function controlFees(transaction, feeControl) {
|
|
|
727
770
|
* @returns The suggested transaction parameters
|
|
728
771
|
*/
|
|
729
772
|
async function getTransactionParams(params, algod) {
|
|
730
|
-
|
|
773
|
+
if (params) {
|
|
774
|
+
return { ...params };
|
|
775
|
+
}
|
|
776
|
+
const p = await algod.getTransactionParams().do();
|
|
777
|
+
return {
|
|
778
|
+
fee: p.fee,
|
|
779
|
+
firstValid: p.firstValid,
|
|
780
|
+
lastValid: p.lastValid,
|
|
781
|
+
genesisID: p.genesisID,
|
|
782
|
+
genesisHash: p.genesisHash,
|
|
783
|
+
minFee: p.minFee,
|
|
784
|
+
};
|
|
731
785
|
}
|
|
732
786
|
/**
|
|
733
787
|
* @deprecated Use `atc.clone().buildGroup()` instead.
|
|
@@ -745,5 +799,5 @@ function getAtomicTransactionComposerTransactions(atc) {
|
|
|
745
799
|
}
|
|
746
800
|
}
|
|
747
801
|
|
|
748
|
-
export { MAX_APP_CALL_ACCOUNT_REFERENCES, MAX_APP_CALL_FOREIGN_REFERENCES, MAX_TRANSACTION_GROUP_SIZE, capTransactionFee, controlFees, encodeLease, encodeTransactionNote, getAtomicTransactionComposerTransactions, getSenderAddress, getSenderTransactionSigner, getTransactionParams, getTransactionWithSigner,
|
|
802
|
+
export { MAX_APP_CALL_ACCOUNT_REFERENCES, MAX_APP_CALL_FOREIGN_REFERENCES, MAX_TRANSACTION_GROUP_SIZE, capTransactionFee, controlFees, encodeLease, encodeTransactionNote, getABIReturnValue, getAtomicTransactionComposerTransactions, getSenderAddress, getSenderTransactionSigner, getTransactionParams, getTransactionWithSigner, populateAppCallResources, sendAtomicTransactionComposer, sendGroupOfTransactions, sendTransaction, signTransaction, waitForConfirmation };
|
|
749
803
|
//# sourceMappingURL=transaction.mjs.map
|