@algorandfoundation/algokit-utils 7.0.0 → 8.0.0

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.
Files changed (148) hide show
  1. package/README.md +14 -3
  2. package/account/account.d.ts +4 -1
  3. package/account/account.js +4 -3
  4. package/account/account.js.map +1 -1
  5. package/account/account.mjs +5 -4
  6. package/account/account.mjs.map +1 -1
  7. package/account/get-dispenser-account.d.ts +1 -1
  8. package/amount.d.ts +1 -0
  9. package/amount.js +3 -2
  10. package/amount.js.map +1 -1
  11. package/amount.mjs +3 -3
  12. package/amount.mjs.map +1 -1
  13. package/app-client.d.ts +4 -4
  14. package/app-client.js +4 -4
  15. package/app-client.js.map +1 -1
  16. package/app-client.mjs +4 -4
  17. package/app-client.mjs.map +1 -1
  18. package/app-deploy.js +23 -5
  19. package/app-deploy.js.map +1 -1
  20. package/app-deploy.mjs +24 -6
  21. package/app-deploy.mjs.map +1 -1
  22. package/app.js +7 -4
  23. package/app.js.map +1 -1
  24. package/app.mjs +7 -4
  25. package/app.mjs.map +1 -1
  26. package/index.js +1 -1
  27. package/index.mjs +2 -2
  28. package/indexer-lookup.d.ts +10 -8
  29. package/indexer-lookup.js +14 -10
  30. package/indexer-lookup.js.map +1 -1
  31. package/indexer-lookup.mjs +14 -10
  32. package/indexer-lookup.mjs.map +1 -1
  33. package/network-client.d.ts +1 -7
  34. package/network-client.js +2 -9
  35. package/network-client.js.map +1 -1
  36. package/network-client.mjs +2 -9
  37. package/network-client.mjs.map +1 -1
  38. package/package.json +2 -2
  39. package/testing/_asset.d.ts +2 -1
  40. package/testing/account.d.ts +4 -3
  41. package/testing/account.js +8 -2
  42. package/testing/account.js.map +1 -1
  43. package/testing/account.mjs +9 -3
  44. package/testing/account.mjs.map +1 -1
  45. package/testing/fixtures/algorand-fixture.js +5 -6
  46. package/testing/fixtures/algorand-fixture.js.map +1 -1
  47. package/testing/fixtures/algorand-fixture.mjs +5 -6
  48. package/testing/fixtures/algorand-fixture.mjs.map +1 -1
  49. package/testing/test-logger.js +7 -1
  50. package/testing/test-logger.js.map +1 -1
  51. package/testing/test-logger.mjs +7 -1
  52. package/testing/test-logger.mjs.map +1 -1
  53. package/transaction/perform-atomic-transaction-composer-simulate.d.ts +4 -1
  54. package/transaction/perform-atomic-transaction-composer-simulate.js +14 -10
  55. package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
  56. package/transaction/perform-atomic-transaction-composer-simulate.mjs +15 -11
  57. package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
  58. package/transaction/transaction.d.ts +1 -17
  59. package/transaction/transaction.js +110 -82
  60. package/transaction/transaction.js.map +1 -1
  61. package/transaction/transaction.mjs +112 -83
  62. package/transaction/transaction.mjs.map +1 -1
  63. package/transfer/transfer.js +3 -1
  64. package/transfer/transfer.js.map +1 -1
  65. package/transfer/transfer.mjs +3 -1
  66. package/transfer/transfer.mjs.map +1 -1
  67. package/types/account-manager.d.ts +20 -20
  68. package/types/account-manager.js +27 -20
  69. package/types/account-manager.js.map +1 -1
  70. package/types/account-manager.mjs +28 -21
  71. package/types/account-manager.mjs.map +1 -1
  72. package/types/account.d.ts +8 -8
  73. package/types/account.js +2 -2
  74. package/types/account.js.map +1 -1
  75. package/types/account.mjs +3 -3
  76. package/types/account.mjs.map +1 -1
  77. package/types/algo-http-client-with-retry.d.ts +1 -2
  78. package/types/algo-http-client-with-retry.js +33 -3
  79. package/types/algo-http-client-with-retry.js.map +1 -1
  80. package/types/algo-http-client-with-retry.mjs +32 -2
  81. package/types/algo-http-client-with-retry.mjs.map +1 -1
  82. package/types/algorand-client-transaction-creator.d.ts +11 -11
  83. package/types/algorand-client-transaction-sender.d.ts +97 -97
  84. package/types/algorand-client-transaction-sender.js.map +1 -1
  85. package/types/algorand-client-transaction-sender.mjs.map +1 -1
  86. package/types/algorand-client.d.ts +3 -3
  87. package/types/algorand-client.js +1 -1
  88. package/types/algorand-client.js.map +1 -1
  89. package/types/algorand-client.mjs +1 -1
  90. package/types/algorand-client.mjs.map +1 -1
  91. package/types/app-client.d.ts +280 -279
  92. package/types/app-client.js +10 -10
  93. package/types/app-client.js.map +1 -1
  94. package/types/app-client.mjs +11 -11
  95. package/types/app-client.mjs.map +1 -1
  96. package/types/app-deployer.d.ts +4 -4
  97. package/types/app-deployer.js +22 -23
  98. package/types/app-deployer.js.map +1 -1
  99. package/types/app-deployer.mjs +23 -24
  100. package/types/app-deployer.mjs.map +1 -1
  101. package/types/app-factory.d.ts +128 -138
  102. package/types/app-factory.js +4 -3
  103. package/types/app-factory.js.map +1 -1
  104. package/types/app-factory.mjs +5 -4
  105. package/types/app-factory.mjs.map +1 -1
  106. package/types/app-manager.d.ts +5 -5
  107. package/types/app-manager.js +11 -15
  108. package/types/app-manager.js.map +1 -1
  109. package/types/app-manager.mjs +12 -16
  110. package/types/app-manager.mjs.map +1 -1
  111. package/types/app.d.ts +4 -4
  112. package/types/app.js.map +1 -1
  113. package/types/app.mjs.map +1 -1
  114. package/types/asset-manager.d.ts +5 -5
  115. package/types/asset-manager.js +8 -11
  116. package/types/asset-manager.js.map +1 -1
  117. package/types/asset-manager.mjs +8 -11
  118. package/types/asset-manager.mjs.map +1 -1
  119. package/types/client-manager.d.ts +2 -9
  120. package/types/client-manager.js +9 -19
  121. package/types/client-manager.js.map +1 -1
  122. package/types/client-manager.mjs +9 -19
  123. package/types/client-manager.mjs.map +1 -1
  124. package/types/composer.d.ts +22 -22
  125. package/types/composer.js +73 -83
  126. package/types/composer.js.map +1 -1
  127. package/types/composer.mjs +74 -84
  128. package/types/composer.mjs.map +1 -1
  129. package/types/dispenser-client.d.ts +2 -1
  130. package/types/dispenser-client.js +5 -1
  131. package/types/dispenser-client.js.map +1 -1
  132. package/types/dispenser-client.mjs +5 -1
  133. package/types/dispenser-client.mjs.map +1 -1
  134. package/types/indexer.d.ts +74 -755
  135. package/types/indexer.js.map +1 -1
  136. package/types/indexer.mjs.map +1 -1
  137. package/types/kmd-account-manager.d.ts +2 -2
  138. package/types/kmd-account-manager.js.map +1 -1
  139. package/types/kmd-account-manager.mjs.map +1 -1
  140. package/types/network-client.d.ts +1 -1
  141. package/types/network-client.js.map +1 -1
  142. package/types/network-client.mjs.map +1 -1
  143. package/types/testing.d.ts +5 -6
  144. package/types/urlTokenBaseHTTPClient.d.ts +0 -40
  145. package/types/urlTokenBaseHTTPClient.js +0 -153
  146. package/types/urlTokenBaseHTTPClient.js.map +0 -1
  147. package/types/urlTokenBaseHTTPClient.mjs +0 -151
  148. package/types/urlTokenBaseHTTPClient.mjs.map +0 -1
package/types/composer.js CHANGED
@@ -10,8 +10,10 @@ var types_networkClient = require('./network-client.js');
10
10
 
11
11
  var AtomicTransactionComposer = algosdk.AtomicTransactionComposer;
12
12
  var isTransactionWithSigner = algosdk.isTransactionWithSigner;
13
- var encodeAddress = algosdk.encodeAddress;
14
13
  var modelsv2 = algosdk.modelsv2;
14
+ const address = (address) => {
15
+ return typeof address === 'string' ? algosdk.Address.fromString(address) : address;
16
+ };
15
17
  const MAX_TRANSACTION_GROUP_SIZE = 16;
16
18
  /** TransactionComposer helps you compose and execute transactions as a transaction group. */
17
19
  class TransactionComposer {
@@ -27,7 +29,7 @@ class TransactionComposer {
27
29
  /** Transactions that have not yet been composed */
28
30
  this.txns = [];
29
31
  /** The default transaction validity window */
30
- this.defaultValidityWindow = 10;
32
+ this.defaultValidityWindow = 10n;
31
33
  /** Whether the validity window was explicitly set on construction */
32
34
  this.defaultValidityWindowIsExplicit = false;
33
35
  this.algod = params.algod;
@@ -47,7 +49,7 @@ class TransactionComposer {
47
49
  addTransaction(transaction, signer) {
48
50
  this.txns.push({
49
51
  txn: transaction,
50
- signer: signer ?? this.getSigner(algosdk.encodeAddress(transaction.from.publicKey)),
52
+ signer: signer ?? this.getSigner(transaction.sender),
51
53
  type: 'txnWithSigner',
52
54
  });
53
55
  return this;
@@ -242,13 +244,11 @@ class TransactionComposer {
242
244
  return this;
243
245
  }
244
246
  /** Build an ATC and return transactions ready to be incorporated into a broader set of transactions this composer is composing */
245
- buildAtc(atc, processTransaction) {
247
+ buildAtc(atc) {
246
248
  const group = atc.buildGroup();
247
249
  const txnWithSigners = group.map((ts, idx) => {
248
250
  // Remove underlying group ID from the transaction since it will be re-grouped when this TransactionComposer is built
249
251
  ts.txn.group = undefined;
250
- // Process transaction if a function is provided
251
- ts.txn = processTransaction?.(ts.txn, idx) ?? ts.txn;
252
252
  // If this was a method call stash the ABIMethod for later
253
253
  if (atc['methodCalls'].get(idx)) {
254
254
  this.txnMethodMap.set(ts.txn.txID(), atc['methodCalls'].get(idx));
@@ -257,39 +257,42 @@ class TransactionComposer {
257
257
  });
258
258
  return txnWithSigners;
259
259
  }
260
- commonTxnBuildStep(params, txn, suggestedParams) {
260
+ commonTxnBuildStep(buildTxn, params, txnParams) {
261
+ // We are going to mutate suggested params, let's create a clone first
262
+ txnParams.suggestedParams = { ...txnParams.suggestedParams };
261
263
  if (params.lease)
262
- txn.addLease(transaction.encodeLease(params.lease));
264
+ txnParams.lease = transaction.encodeLease(params.lease);
263
265
  if (params.rekeyTo)
264
- txn.addRekey(params.rekeyTo);
266
+ txnParams.rekeyTo = address(params.rekeyTo);
265
267
  const encoder = new TextEncoder();
266
268
  if (params.note)
267
- txn.note = typeof params.note === 'string' ? encoder.encode(params.note) : params.note;
269
+ txnParams.note = (typeof params.note === 'string' ? encoder.encode(params.note) : params.note);
268
270
  if (params.firstValidRound) {
269
- txn.firstRound = Number(params.firstValidRound);
271
+ txnParams.suggestedParams.firstValid = params.firstValidRound;
270
272
  }
271
273
  if (params.lastValidRound) {
272
- txn.lastRound = Number(params.lastValidRound);
274
+ txnParams.suggestedParams.lastValid = params.lastValidRound;
273
275
  }
274
276
  else {
275
277
  // If the validity window isn't set in this transaction or by default and we are pointing at
276
278
  // LocalNet set a bigger window to avoid dead transactions
277
- const window = params.validityWindow ??
278
- (!this.defaultValidityWindowIsExplicit && types_networkClient.genesisIdIsLocalNet(suggestedParams.genesisID) ? 1000 : this.defaultValidityWindow);
279
- txn.lastRound = txn.firstRound + window;
279
+ const window = params.validityWindow
280
+ ? BigInt(params.validityWindow)
281
+ : !this.defaultValidityWindowIsExplicit && types_networkClient.genesisIdIsLocalNet(txnParams.suggestedParams.genesisID ?? 'unknown')
282
+ ? 1000n
283
+ : this.defaultValidityWindow;
284
+ txnParams.suggestedParams.lastValid = BigInt(txnParams.suggestedParams.firstValid) + window;
280
285
  }
281
286
  if (params.staticFee !== undefined && params.extraFee !== undefined) {
282
287
  throw Error('Cannot set both staticFee and extraFee');
283
288
  }
284
289
  if (params.staticFee !== undefined) {
285
- txn.fee = Number(params.staticFee.microAlgo);
290
+ txnParams.suggestedParams.fee = params.staticFee.microAlgo;
291
+ txnParams.suggestedParams.flatFee = true;
286
292
  }
287
- else {
288
- txn.fee = txn.estimateSize() * suggestedParams.fee || algosdk.ALGORAND_MIN_TX_FEE;
289
- if (params.extraFee)
290
- txn.fee += Number(params.extraFee.microAlgo);
291
- }
292
- txn.flatFee = true;
293
+ const txn = buildTxn(txnParams);
294
+ if (params.extraFee)
295
+ txn.fee += params.extraFee.microAlgo;
293
296
  if (params.maxFee !== undefined && txn.fee > params.maxFee.microAlgo) {
294
297
  throw Error(`Transaction fee ${txn.fee} µALGO is greater than maxFee ${params.maxFee}`);
295
298
  }
@@ -344,7 +347,7 @@ class TransactionComposer {
344
347
  ? 'signer' in params.signer
345
348
  ? params.signer.signer
346
349
  : params.signer
347
- : this.getSigner(encodeAddress(txn.from.publicKey))
350
+ : this.getSigner(txn.sender)
348
351
  : TransactionComposer.NULL_SIGNER,
349
352
  });
350
353
  }
@@ -361,7 +364,7 @@ class TransactionComposer {
361
364
  ? (await this.appManager.compileTeal(params.clearStateProgram)).compiledBase64ToBytes
362
365
  : params.clearStateProgram
363
366
  : undefined;
364
- methodAtc.addMethodCall({
367
+ const txnParams = {
365
368
  appID: appId,
366
369
  sender: params.sender,
367
370
  suggestedParams,
@@ -396,43 +399,45 @@ class TransactionComposer {
396
399
  note: undefined,
397
400
  lease: undefined,
398
401
  rekeyTo: undefined,
399
- });
402
+ };
403
+ // Build the transaction
404
+ this.commonTxnBuildStep((txnParams) => {
405
+ methodAtc.addMethodCall(txnParams);
406
+ return methodAtc.buildGroup()[methodAtc.count() - 1].txn;
407
+ }, params, txnParams);
400
408
  // Process the ATC to get a set of transactions ready for broader grouping
401
- // and with the common build step to set fees and validity rounds
402
- return this.buildAtc(methodAtc, (txn, idx) => idx === methodAtc.count() - 1 ? this.commonTxnBuildStep(params, txn, suggestedParams) : txn);
409
+ return this.buildAtc(methodAtc);
403
410
  }
404
411
  buildPayment(params, suggestedParams) {
405
- const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
406
- from: params.sender,
407
- to: params.receiver,
412
+ return this.commonTxnBuildStep(algosdk.makePaymentTxnWithSuggestedParamsFromObject, params, {
413
+ sender: params.sender,
414
+ receiver: params.receiver,
408
415
  amount: params.amount.microAlgo,
409
416
  closeRemainderTo: params.closeRemainderTo,
410
417
  suggestedParams,
411
418
  });
412
- return this.commonTxnBuildStep(params, txn, suggestedParams);
413
419
  }
414
420
  buildAssetCreate(params, suggestedParams) {
415
- const txn = algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({
416
- from: params.sender,
421
+ return this.commonTxnBuildStep(algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject, params, {
422
+ sender: params.sender,
417
423
  total: params.total,
418
424
  decimals: params.decimals ?? 0,
419
425
  assetName: params.assetName,
420
426
  unitName: params.unitName,
421
427
  assetURL: params.url,
422
428
  defaultFrozen: params.defaultFrozen ?? false,
423
- assetMetadataHash: params.metadataHash,
429
+ assetMetadataHash: typeof params.metadataHash === 'string' ? Buffer.from(params.metadataHash, 'utf-8') : params.metadataHash,
424
430
  manager: params.manager,
425
431
  reserve: params.reserve,
426
432
  freeze: params.freeze,
427
433
  clawback: params.clawback,
428
434
  suggestedParams,
429
435
  });
430
- return this.commonTxnBuildStep(params, txn, suggestedParams);
431
436
  }
432
437
  buildAssetConfig(params, suggestedParams) {
433
- const txn = algosdk.makeAssetConfigTxnWithSuggestedParamsFromObject({
434
- from: params.sender,
435
- assetIndex: Number(params.assetId),
438
+ return this.commonTxnBuildStep(algosdk.makeAssetConfigTxnWithSuggestedParamsFromObject, params, {
439
+ sender: params.sender,
440
+ assetIndex: params.assetId,
436
441
  suggestedParams,
437
442
  manager: params.manager,
438
443
  reserve: params.reserve,
@@ -440,40 +445,36 @@ class TransactionComposer {
440
445
  clawback: params.clawback,
441
446
  strictEmptyAddressChecking: false,
442
447
  });
443
- return this.commonTxnBuildStep(params, txn, suggestedParams);
444
448
  }
445
449
  buildAssetDestroy(params, suggestedParams) {
446
- const txn = algosdk.makeAssetDestroyTxnWithSuggestedParamsFromObject({
447
- from: params.sender,
448
- assetIndex: Number(params.assetId),
450
+ return this.commonTxnBuildStep(algosdk.makeAssetDestroyTxnWithSuggestedParamsFromObject, params, {
451
+ sender: params.sender,
452
+ assetIndex: params.assetId,
449
453
  suggestedParams,
450
454
  });
451
- return this.commonTxnBuildStep(params, txn, suggestedParams);
452
455
  }
453
456
  buildAssetFreeze(params, suggestedParams) {
454
- const txn = algosdk.makeAssetFreezeTxnWithSuggestedParamsFromObject({
455
- from: params.sender,
456
- assetIndex: Number(params.assetId),
457
+ return this.commonTxnBuildStep(algosdk.makeAssetFreezeTxnWithSuggestedParamsFromObject, params, {
458
+ sender: params.sender,
459
+ assetIndex: params.assetId,
457
460
  freezeTarget: params.account,
458
- freezeState: params.frozen,
461
+ frozen: params.frozen,
459
462
  suggestedParams,
460
463
  });
461
- return this.commonTxnBuildStep(params, txn, suggestedParams);
462
464
  }
463
465
  buildAssetTransfer(params, suggestedParams) {
464
- const txn = algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({
465
- from: params.sender,
466
- to: params.receiver,
467
- assetIndex: Number(params.assetId),
466
+ return this.commonTxnBuildStep(algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject, params, {
467
+ sender: params.sender,
468
+ receiver: params.receiver,
469
+ assetIndex: params.assetId,
468
470
  amount: params.amount,
469
471
  suggestedParams,
470
472
  closeRemainderTo: params.closeAssetTo,
471
- revocationTarget: params.clawbackTarget,
473
+ assetSender: params.clawbackTarget,
472
474
  });
473
- return this.commonTxnBuildStep(params, txn, suggestedParams);
474
475
  }
475
476
  async buildAppCall(params, suggestedParams) {
476
- const appId = Number('appId' in params ? params.appId : 0n);
477
+ const appId = 'appId' in params ? params.appId : 0n;
477
478
  const approvalProgram = 'approvalProgram' in params
478
479
  ? typeof params.approvalProgram === 'string'
479
480
  ? (await this.appManager.compileTeal(params.approvalProgram)).compiledBase64ToBytes
@@ -485,7 +486,7 @@ class TransactionComposer {
485
486
  : params.clearStateProgram
486
487
  : undefined;
487
488
  const sdkParams = {
488
- from: params.sender,
489
+ sender: params.sender,
489
490
  suggestedParams,
490
491
  appArgs: params.args,
491
492
  onComplete: params.onComplete ?? algosdk.OnApplicationComplete.NoOpOC,
@@ -496,12 +497,11 @@ class TransactionComposer {
496
497
  approvalProgram,
497
498
  clearProgram: clearStateProgram,
498
499
  };
499
- let txn;
500
- if (appId === 0) {
500
+ if (appId === 0n) {
501
501
  if (sdkParams.approvalProgram === undefined || sdkParams.clearProgram === undefined) {
502
502
  throw new Error('approvalProgram and clearStateProgram are required for application creation');
503
503
  }
504
- txn = algosdk.makeApplicationCreateTxnFromObject({
504
+ return this.commonTxnBuildStep(algosdk.makeApplicationCreateTxnFromObject, params, {
505
505
  ...sdkParams,
506
506
  extraPages: 'extraProgramPages' in params
507
507
  ? (params.extraProgramPages ?? Math.floor((approvalProgram.length + clearStateProgram.length) / types_app.APP_PAGE_MAX_SIZE))
@@ -515,38 +515,28 @@ class TransactionComposer {
515
515
  });
516
516
  }
517
517
  else {
518
- txn = algosdk.makeApplicationCallTxnFromObject({ ...sdkParams, appIndex: appId });
518
+ return this.commonTxnBuildStep(algosdk.makeApplicationCallTxnFromObject, params, { ...sdkParams, appIndex: appId });
519
519
  }
520
- return this.commonTxnBuildStep(params, txn, suggestedParams);
521
520
  }
522
521
  buildKeyReg(params, suggestedParams) {
523
- let txn;
524
522
  if ('voteKey' in params) {
525
- // algosdk throws when voteFirst is 0, so we need to set it to 1, then switch back to 0 after creating the transaction
526
- const voteFirst = params.voteFirst === 0n ? 1n : params.voteFirst;
527
- txn = algosdk.makeKeyRegistrationTxnWithSuggestedParamsFromObject({
528
- from: params.sender,
523
+ return this.commonTxnBuildStep(algosdk.makeKeyRegistrationTxnWithSuggestedParamsFromObject, params, {
524
+ sender: params.sender,
529
525
  voteKey: params.voteKey,
530
526
  selectionKey: params.selectionKey,
531
- voteFirst: Number(voteFirst),
532
- voteLast: Number(params.voteLast),
533
- voteKeyDilution: Number(params.voteKeyDilution),
527
+ voteFirst: params.voteFirst,
528
+ voteLast: params.voteLast,
529
+ voteKeyDilution: params.voteKeyDilution,
534
530
  suggestedParams,
535
531
  nonParticipation: false,
536
532
  stateProofKey: params.stateProofKey,
537
533
  });
538
- if (params.voteFirst === 0n) {
539
- txn.voteFirst = 0;
540
- }
541
- }
542
- else {
543
- txn = algosdk.makeKeyRegistrationTxnWithSuggestedParamsFromObject({
544
- from: params.sender,
545
- suggestedParams,
546
- nonParticipation: params.preventAccountFromEverParticipatingAgain,
547
- });
548
534
  }
549
- return this.commonTxnBuildStep(params, txn, suggestedParams);
535
+ return this.commonTxnBuildStep(algosdk.makeKeyRegistrationTxnWithSuggestedParamsFromObject, params, {
536
+ sender: params.sender,
537
+ suggestedParams,
538
+ nonParticipation: params.preventAccountFromEverParticipatingAgain,
539
+ });
550
540
  }
551
541
  /** Builds all transaction types apart from `txnWithSigner`, `atc` and `methodCall` since those ones can have custom signers that need to be retrieved. */
552
542
  async buildTxn(txn, suggestedParams) {
@@ -679,9 +669,9 @@ class TransactionComposer {
679
669
  const group = (await this.build()).transactions;
680
670
  let waitRounds = params?.maxRoundsToWaitForConfirmation;
681
671
  if (waitRounds === undefined) {
682
- const lastRound = group.reduce((max, txn) => Math.max(txn.txn.lastRound, max), 0);
683
- const { firstRound } = await this.getSuggestedParams();
684
- waitRounds = lastRound - firstRound + 1;
672
+ const lastRound = group.reduce((max, txn) => (txn.txn.lastValid > max ? txn.txn.lastValid : BigInt(max)), 0n);
673
+ const { firstValid: firstRound } = await this.getSuggestedParams();
674
+ waitRounds = Number(BigInt(lastRound) - BigInt(firstRound)) + 1;
685
675
  }
686
676
  return await transaction.sendAtomicTransactionComposer({
687
677
  atc: this.atc,