@algorandfoundation/algokit-utils 9.2.0 → 9.2.1-beta.2

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 (340) hide show
  1. package/_virtual/_rolldown/runtime.js +33 -0
  2. package/_virtual/_rolldown/runtime.mjs +13 -0
  3. package/account/account.d.ts +25 -30
  4. package/account/account.js +151 -146
  5. package/account/account.js.map +1 -1
  6. package/account/account.mjs +149 -144
  7. package/account/account.mjs.map +1 -1
  8. package/account/get-account-config-from-environment.d.ts +7 -2
  9. package/account/get-account-config-from-environment.js +19 -21
  10. package/account/get-account-config-from-environment.js.map +1 -1
  11. package/account/get-account-config-from-environment.mjs +19 -19
  12. package/account/get-account-config-from-environment.mjs.map +1 -1
  13. package/account/get-account.d.ts +14 -12
  14. package/account/get-account.js +56 -59
  15. package/account/get-account.js.map +1 -1
  16. package/account/get-account.mjs +56 -57
  17. package/account/get-account.mjs.map +1 -1
  18. package/account/get-dispenser-account.d.ts +9 -5
  19. package/account/get-dispenser-account.js +20 -18
  20. package/account/get-dispenser-account.js.map +1 -1
  21. package/account/get-dispenser-account.mjs +20 -16
  22. package/account/get-dispenser-account.mjs.map +1 -1
  23. package/account/mnemonic-account.d.ts +7 -3
  24. package/account/mnemonic-account.js +17 -17
  25. package/account/mnemonic-account.js.map +1 -1
  26. package/account/mnemonic-account.mjs +15 -15
  27. package/account/mnemonic-account.mjs.map +1 -1
  28. package/amount.d.ts +40 -35
  29. package/amount.js +33 -34
  30. package/amount.js.map +1 -1
  31. package/amount.mjs +33 -32
  32. package/amount.mjs.map +1 -1
  33. package/app-client.d.ts +10 -6
  34. package/app-client.js +91 -86
  35. package/app-client.js.map +1 -1
  36. package/app-client.mjs +91 -84
  37. package/app-client.mjs.map +1 -1
  38. package/app-deploy.d.ts +26 -24
  39. package/app-deploy.js +235 -253
  40. package/app-deploy.js.map +1 -1
  41. package/app-deploy.mjs +233 -251
  42. package/app-deploy.mjs.map +1 -1
  43. package/app.d.ts +45 -46
  44. package/app.js +253 -271
  45. package/app.js.map +1 -1
  46. package/app.mjs +249 -267
  47. package/app.mjs.map +1 -1
  48. package/asset.d.ts +16 -12
  49. package/asset.js +116 -122
  50. package/asset.js.map +1 -1
  51. package/asset.mjs +116 -120
  52. package/asset.mjs.map +1 -1
  53. package/config.d.ts +7 -2
  54. package/config.js +5 -7
  55. package/config.js.map +1 -1
  56. package/config.mjs +5 -4
  57. package/config.mjs.map +1 -1
  58. package/debugging/debugging.d.ts +5 -1
  59. package/debugging/debugging.js +11 -11
  60. package/debugging/debugging.js.map +1 -1
  61. package/debugging/debugging.mjs +11 -9
  62. package/debugging/debugging.mjs.map +1 -1
  63. package/dispenser-client.d.ts +7 -2
  64. package/dispenser-client.js +23 -24
  65. package/dispenser-client.js.map +1 -1
  66. package/dispenser-client.mjs +23 -22
  67. package/dispenser-client.mjs.map +1 -1
  68. package/index.d.ts +27 -18
  69. package/index.js +140 -143
  70. package/index.mjs +27 -29
  71. package/indexer-lookup.d.ts +18 -11
  72. package/indexer-lookup.js +112 -120
  73. package/indexer-lookup.js.map +1 -1
  74. package/indexer-lookup.mjs +105 -118
  75. package/indexer-lookup.mjs.map +1 -1
  76. package/localnet/get-kmd-wallet-account.d.ts +9 -7
  77. package/localnet/get-kmd-wallet-account.js +28 -26
  78. package/localnet/get-kmd-wallet-account.js.map +1 -1
  79. package/localnet/get-kmd-wallet-account.mjs +28 -24
  80. package/localnet/get-kmd-wallet-account.mjs.map +1 -1
  81. package/localnet/get-localnet-dispenser-account.d.ts +7 -5
  82. package/localnet/get-localnet-dispenser-account.js +17 -15
  83. package/localnet/get-localnet-dispenser-account.js.map +1 -1
  84. package/localnet/get-localnet-dispenser-account.mjs +17 -13
  85. package/localnet/get-localnet-dispenser-account.mjs.map +1 -1
  86. package/localnet/get-or-create-kmd-wallet-account.d.ts +10 -8
  87. package/localnet/get-or-create-kmd-wallet-account.js +28 -26
  88. package/localnet/get-or-create-kmd-wallet-account.js.map +1 -1
  89. package/localnet/get-or-create-kmd-wallet-account.mjs +28 -24
  90. package/localnet/get-or-create-kmd-wallet-account.mjs.map +1 -1
  91. package/localnet/is-localnet.d.ts +7 -3
  92. package/localnet/is-localnet.js +9 -10
  93. package/localnet/is-localnet.js.map +1 -1
  94. package/localnet/is-localnet.mjs +9 -8
  95. package/localnet/is-localnet.mjs.map +1 -1
  96. package/network-client.d.ts +17 -15
  97. package/network-client.js +115 -116
  98. package/network-client.js.map +1 -1
  99. package/network-client.mjs +115 -114
  100. package/network-client.mjs.map +1 -1
  101. package/package.json +12 -3
  102. package/testing/account.d.ts +11 -9
  103. package/testing/account.js +31 -33
  104. package/testing/account.js.map +1 -1
  105. package/testing/account.mjs +29 -31
  106. package/testing/account.mjs.map +1 -1
  107. package/testing/fixtures/algokit-log-capture-fixture.d.ts +7 -2
  108. package/testing/fixtures/algokit-log-capture-fixture.js +36 -41
  109. package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
  110. package/testing/fixtures/algokit-log-capture-fixture.mjs +36 -39
  111. package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
  112. package/testing/fixtures/algorand-fixture.d.ts +9 -4
  113. package/testing/fixtures/algorand-fixture.js +67 -62
  114. package/testing/fixtures/algorand-fixture.js.map +1 -1
  115. package/testing/fixtures/algorand-fixture.mjs +66 -59
  116. package/testing/fixtures/algorand-fixture.mjs.map +1 -1
  117. package/testing/index.d.ts +7 -5
  118. package/testing/index.js +13 -18
  119. package/testing/index.mjs +7 -7
  120. package/testing/indexer.d.ts +5 -1
  121. package/testing/indexer.js +28 -37
  122. package/testing/indexer.js.map +1 -1
  123. package/testing/indexer.mjs +28 -35
  124. package/testing/indexer.mjs.map +1 -1
  125. package/testing/test-logger.d.ts +41 -36
  126. package/testing/test-logger.js +71 -76
  127. package/testing/test-logger.js.map +1 -1
  128. package/testing/test-logger.mjs +71 -74
  129. package/testing/test-logger.mjs.map +1 -1
  130. package/testing/transaction-logger.d.ts +30 -27
  131. package/testing/transaction-logger.js +77 -93
  132. package/testing/transaction-logger.js.map +1 -1
  133. package/testing/transaction-logger.mjs +74 -90
  134. package/testing/transaction-logger.mjs.map +1 -1
  135. package/transaction/legacy-bridge.js +100 -111
  136. package/transaction/legacy-bridge.js.map +1 -1
  137. package/transaction/legacy-bridge.mjs +97 -108
  138. package/transaction/legacy-bridge.mjs.map +1 -1
  139. package/transaction/perform-atomic-transaction-composer-simulate.d.ts +7 -5
  140. package/transaction/perform-atomic-transaction-composer-simulate.js +31 -36
  141. package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
  142. package/transaction/perform-atomic-transaction-composer-simulate.mjs +28 -33
  143. package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
  144. package/transaction/transaction.d.ts +34 -35
  145. package/transaction/transaction.js +716 -914
  146. package/transaction/transaction.js.map +1 -1
  147. package/transaction/transaction.mjs +713 -911
  148. package/transaction/transaction.mjs.map +1 -1
  149. package/transfer/transfer-algos.d.ts +9 -5
  150. package/transfer/transfer-algos.js +26 -27
  151. package/transfer/transfer-algos.js.map +1 -1
  152. package/transfer/transfer-algos.mjs +26 -25
  153. package/transfer/transfer-algos.mjs.map +1 -1
  154. package/transfer/transfer.d.ts +11 -8
  155. package/transfer/transfer.js +94 -100
  156. package/transfer/transfer.js.map +1 -1
  157. package/transfer/transfer.mjs +94 -98
  158. package/transfer/transfer.mjs.map +1 -1
  159. package/types/account-manager.d.ts +432 -429
  160. package/types/account-manager.js +591 -602
  161. package/types/account-manager.js.map +1 -1
  162. package/types/account-manager.mjs +587 -599
  163. package/types/account-manager.mjs.map +1 -1
  164. package/types/account.d.ts +192 -202
  165. package/types/account.js +91 -88
  166. package/types/account.js.map +1 -1
  167. package/types/account.mjs +88 -86
  168. package/types/account.mjs.map +1 -1
  169. package/types/algo-http-client-with-retry.d.ts +15 -10
  170. package/types/algo-http-client-with-retry.js +70 -92
  171. package/types/algo-http-client-with-retry.js.map +1 -1
  172. package/types/algo-http-client-with-retry.mjs +69 -90
  173. package/types/algo-http-client-with-retry.mjs.map +1 -1
  174. package/types/algorand-client-transaction-creator.d.ts +778 -771
  175. package/types/algorand-client-transaction-creator.js +733 -732
  176. package/types/algorand-client-transaction-creator.js.map +1 -1
  177. package/types/algorand-client-transaction-creator.mjs +732 -730
  178. package/types/algorand-client-transaction-creator.mjs.map +1 -1
  179. package/types/algorand-client-transaction-sender.d.ts +1090 -1360
  180. package/types/algorand-client-transaction-sender.js +930 -961
  181. package/types/algorand-client-transaction-sender.js.map +1 -1
  182. package/types/algorand-client-transaction-sender.mjs +927 -959
  183. package/types/algorand-client-transaction-sender.mjs.map +1 -1
  184. package/types/algorand-client.d.ts +239 -236
  185. package/types/algorand-client.js +322 -320
  186. package/types/algorand-client.js.map +1 -1
  187. package/types/algorand-client.mjs +321 -318
  188. package/types/algorand-client.mjs.map +1 -1
  189. package/types/amount.d.ts +47 -43
  190. package/types/amount.js +66 -70
  191. package/types/amount.js.map +1 -1
  192. package/types/amount.mjs +63 -68
  193. package/types/amount.mjs.map +1 -1
  194. package/types/app-arc56.d.ts +235 -272
  195. package/types/app-arc56.js +124 -170
  196. package/types/app-arc56.js.map +1 -1
  197. package/types/app-arc56.mjs +121 -168
  198. package/types/app-arc56.mjs.map +1 -1
  199. package/types/app-client.d.ts +1128 -2009
  200. package/types/app-client.js +1633 -1791
  201. package/types/app-client.js.map +1 -1
  202. package/types/app-client.mjs +1624 -1783
  203. package/types/app-client.mjs.map +1 -1
  204. package/types/app-deployer.d.ts +139 -141
  205. package/types/app-deployer.js +344 -384
  206. package/types/app-deployer.js.map +1 -1
  207. package/types/app-deployer.mjs +341 -382
  208. package/types/app-deployer.mjs.map +1 -1
  209. package/types/app-factory.d.ts +762 -932
  210. package/types/app-factory.js +496 -488
  211. package/types/app-factory.js.map +1 -1
  212. package/types/app-factory.mjs +491 -484
  213. package/types/app-factory.mjs.map +1 -1
  214. package/types/app-manager.d.ts +304 -310
  215. package/types/app-manager.js +422 -475
  216. package/types/app-manager.js.map +1 -1
  217. package/types/app-manager.mjs +419 -473
  218. package/types/app-manager.mjs.map +1 -1
  219. package/types/app-spec.d.ts +118 -117
  220. package/types/app-spec.js +125 -135
  221. package/types/app-spec.js.map +1 -1
  222. package/types/app-spec.mjs +121 -132
  223. package/types/app-spec.mjs.map +1 -1
  224. package/types/app.d.ts +229 -241
  225. package/types/app.js +36 -28
  226. package/types/app.js.map +1 -1
  227. package/types/app.mjs +33 -26
  228. package/types/app.mjs.map +1 -1
  229. package/types/asset-manager.d.ts +204 -199
  230. package/types/asset-manager.js +165 -174
  231. package/types/asset-manager.js.map +1 -1
  232. package/types/asset-manager.mjs +164 -172
  233. package/types/asset-manager.mjs.map +1 -1
  234. package/types/asset.d.ts +95 -91
  235. package/types/asset.js +0 -3
  236. package/types/asset.mjs +0 -2
  237. package/types/async-event-emitter.d.ts +18 -13
  238. package/types/async-event-emitter.js +37 -49
  239. package/types/async-event-emitter.js.map +1 -1
  240. package/types/async-event-emitter.mjs +36 -47
  241. package/types/async-event-emitter.mjs.map +1 -1
  242. package/types/client-manager.d.ts +453 -451
  243. package/types/client-manager.js +602 -598
  244. package/types/client-manager.js.map +1 -1
  245. package/types/client-manager.mjs +597 -594
  246. package/types/client-manager.mjs.map +1 -1
  247. package/types/composer.d.ts +1211 -1258
  248. package/types/composer.js +1436 -1498
  249. package/types/composer.js.map +1 -1
  250. package/types/composer.mjs +1430 -1493
  251. package/types/composer.mjs.map +1 -1
  252. package/types/config.d.ts +53 -48
  253. package/types/config.js +78 -77
  254. package/types/config.js.map +1 -1
  255. package/types/config.mjs +77 -75
  256. package/types/config.mjs.map +1 -1
  257. package/types/debugging.d.ts +25 -23
  258. package/types/debugging.js +9 -11
  259. package/types/debugging.js.map +1 -1
  260. package/types/debugging.mjs +8 -9
  261. package/types/debugging.mjs.map +1 -1
  262. package/types/dispenser-client.d.ts +57 -52
  263. package/types/dispenser-client.js +120 -141
  264. package/types/dispenser-client.js.map +1 -1
  265. package/types/dispenser-client.mjs +119 -139
  266. package/types/dispenser-client.mjs.map +1 -1
  267. package/types/expand.d.ts +5 -3
  268. package/types/expand.js +0 -3
  269. package/types/expand.mjs +0 -2
  270. package/types/indexer.d.ts +104 -100
  271. package/types/indexer.js +36 -31
  272. package/types/indexer.js.map +1 -1
  273. package/types/indexer.mjs +32 -30
  274. package/types/indexer.mjs.map +1 -1
  275. package/types/instance-of.d.ts +5 -3
  276. package/types/instance-of.js +0 -3
  277. package/types/instance-of.mjs +0 -2
  278. package/types/kmd-account-manager.d.ts +75 -70
  279. package/types/kmd-account-manager.js +150 -184
  280. package/types/kmd-account-manager.js.map +1 -1
  281. package/types/kmd-account-manager.mjs +147 -182
  282. package/types/kmd-account-manager.mjs.map +1 -1
  283. package/types/lifecycle-events.d.ts +13 -8
  284. package/types/lifecycle-events.js +10 -7
  285. package/types/lifecycle-events.js.map +1 -1
  286. package/types/lifecycle-events.mjs +9 -7
  287. package/types/lifecycle-events.mjs.map +1 -1
  288. package/types/logging.d.ts +15 -11
  289. package/types/logging.js +30 -31
  290. package/types/logging.js.map +1 -1
  291. package/types/logging.mjs +29 -29
  292. package/types/logging.mjs.map +1 -1
  293. package/types/logic-error.d.ts +33 -29
  294. package/types/logic-error.js +50 -49
  295. package/types/logic-error.js.map +1 -1
  296. package/types/logic-error.mjs +49 -47
  297. package/types/logic-error.mjs.map +1 -1
  298. package/types/network-client.d.ts +32 -27
  299. package/types/network-client.js +10 -9
  300. package/types/network-client.js.map +1 -1
  301. package/types/network-client.mjs +9 -7
  302. package/types/network-client.mjs.map +1 -1
  303. package/types/testing.d.ts +131 -132
  304. package/types/testing.js +0 -3
  305. package/types/testing.mjs +0 -2
  306. package/types/transaction.d.ts +110 -110
  307. package/types/transaction.js +0 -3
  308. package/types/transaction.mjs +0 -2
  309. package/types/transfer.d.ts +70 -66
  310. package/types/transfer.js +0 -3
  311. package/types/transfer.mjs +0 -2
  312. package/util.js +73 -118
  313. package/util.js.map +1 -1
  314. package/util.mjs +73 -116
  315. package/util.mjs.map +1 -1
  316. package/account/index.d.ts +0 -5
  317. package/debugging/index.d.ts +0 -1
  318. package/index.js.map +0 -1
  319. package/index.mjs.map +0 -1
  320. package/localnet/index.d.ts +0 -4
  321. package/testing/_asset.d.ts +0 -3
  322. package/testing/fixtures/index.d.ts +0 -2
  323. package/testing/index.js.map +0 -1
  324. package/testing/index.mjs.map +0 -1
  325. package/transaction/index.d.ts +0 -2
  326. package/transaction/legacy-bridge.d.ts +0 -35
  327. package/transfer/index.d.ts +0 -2
  328. package/types/asset.js.map +0 -1
  329. package/types/asset.mjs.map +0 -1
  330. package/types/expand.js.map +0 -1
  331. package/types/expand.mjs.map +0 -1
  332. package/types/instance-of.js.map +0 -1
  333. package/types/instance-of.mjs.map +0 -1
  334. package/types/testing.js.map +0 -1
  335. package/types/testing.mjs.map +0 -1
  336. package/types/transaction.js.map +0 -1
  337. package/types/transaction.mjs.map +0 -1
  338. package/types/transfer.js.map +0 -1
  339. package/types/transfer.mjs.map +0 -1
  340. package/util.d.ts +0 -48
@@ -1,969 +1,770 @@
1
- 'use strict';
2
-
3
- var algosdk = require('algosdk');
4
- var buffer = require('buffer');
5
- var config = require('../config.js');
6
- var types_lifecycleEvents = require('../types/lifecycle-events.js');
7
- var util = require('../util.js');
8
- var performAtomicTransactionComposerSimulate = require('./perform-atomic-transaction-composer-simulate.js');
9
-
10
- var AtomicTransactionComposer = algosdk.AtomicTransactionComposer;
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
+ const require_config = require("../config.js");
3
+ require("../types/lifecycle-events.js");
4
+ const require_util = require("../util.js");
5
+ const require_perform_atomic_transaction_composer_simulate = require("./perform-atomic-transaction-composer-simulate.js");
6
+ let algosdk = require("algosdk");
7
+ algosdk = require_runtime.__toESM(algosdk);
8
+ let buffer = require("buffer");
9
+ //#region src/transaction/transaction.ts
10
+ var AtomicTransactionComposer = algosdk.default.AtomicTransactionComposer;
11
11
  const MAX_TRANSACTION_GROUP_SIZE = 16;
12
12
  const MAX_APP_CALL_FOREIGN_REFERENCES = 8;
13
13
  const MAX_APP_CALL_ACCOUNT_REFERENCES = 8;
14
14
  /**
15
- * @deprecated Convert your data to a `string` or `Uint8Array`, if using ARC-2 use `TransactionComposer.arc2Note`.
16
- *
17
- * Encodes a transaction note into a byte array ready to be included in an Algorand transaction.
18
- *
19
- * @param note The transaction note
20
- * @returns the transaction note ready for inclusion in a transaction
21
- *
22
- * Case on the value of `data` this either be:
23
- * * `null` | `undefined`: `undefined`
24
- * * `string`: The string value
25
- * * Uint8Array: passthrough
26
- * * Arc2TransactionNote object: ARC-0002 compatible transaction note
27
- * * Else: The object/value converted into a JSON string representation
28
- */
15
+ * @deprecated Convert your data to a `string` or `Uint8Array`, if using ARC-2 use `TransactionComposer.arc2Note`.
16
+ *
17
+ * Encodes a transaction note into a byte array ready to be included in an Algorand transaction.
18
+ *
19
+ * @param note The transaction note
20
+ * @returns the transaction note ready for inclusion in a transaction
21
+ *
22
+ * Case on the value of `data` this either be:
23
+ * * `null` | `undefined`: `undefined`
24
+ * * `string`: The string value
25
+ * * Uint8Array: passthrough
26
+ * * Arc2TransactionNote object: ARC-0002 compatible transaction note
27
+ * * Else: The object/value converted into a JSON string representation
28
+ */
29
29
  function encodeTransactionNote(note) {
30
- if (note == null || typeof note === 'undefined') {
31
- return undefined;
32
- }
33
- else if (typeof note === 'object' && note.constructor === Uint8Array) {
34
- return note;
35
- }
36
- else if (typeof note === 'object' && 'dAppName' in note) {
37
- const arc2Payload = `${note.dAppName}:${note.format}${typeof note.data === 'string' ? note.data : util.asJson(note.data)}`;
38
- const encoder = new TextEncoder();
39
- return encoder.encode(arc2Payload);
40
- }
41
- else {
42
- const n = typeof note === 'string' ? note : util.asJson(note);
43
- const encoder = new TextEncoder();
44
- return encoder.encode(n);
45
- }
30
+ if (note == null || typeof note === "undefined") return;
31
+ else if (typeof note === "object" && note.constructor === Uint8Array) return note;
32
+ else if (typeof note === "object" && "dAppName" in note) {
33
+ const arc2Payload = `${note.dAppName}:${note.format}${typeof note.data === "string" ? note.data : require_util.asJson(note.data)}`;
34
+ return new TextEncoder().encode(arc2Payload);
35
+ } else {
36
+ const n = typeof note === "string" ? note : require_util.asJson(note);
37
+ return new TextEncoder().encode(n);
38
+ }
46
39
  }
47
40
  /** Encodes a transaction lease into a 32-byte array ready to be included in an Algorand transaction.
48
- *
49
- * @param lease The transaction lease as a string or binary array or null/undefined if there is no lease
50
- * @returns the transaction lease ready for inclusion in a transaction or `undefined` if there is no lease
51
- * @throws if the length of the data is > 32 bytes or empty
52
- * @example algokit.encodeLease('UNIQUE_ID')
53
- * @example algokit.encodeLease(new Uint8Array([1, 2, 3]))
54
- */
41
+ *
42
+ * @param lease The transaction lease as a string or binary array or null/undefined if there is no lease
43
+ * @returns the transaction lease ready for inclusion in a transaction or `undefined` if there is no lease
44
+ * @throws if the length of the data is > 32 bytes or empty
45
+ * @example algokit.encodeLease('UNIQUE_ID')
46
+ * @example algokit.encodeLease(new Uint8Array([1, 2, 3]))
47
+ */
55
48
  function encodeLease(lease) {
56
- if (lease === null || typeof lease === 'undefined') {
57
- return undefined;
58
- }
59
- else if (typeof lease === 'object' && lease.constructor === Uint8Array) {
60
- if (lease.length === 0 || lease.length > 32) {
61
- throw new Error(`Received invalid lease; expected something with length between 1 and 32, but received bytes with length ${lease.length}`);
62
- }
63
- if (lease.length === 32)
64
- return lease;
65
- const lease32 = new Uint8Array(32);
66
- lease32.set(lease, 0);
67
- return lease32;
68
- }
69
- else if (typeof lease === 'string') {
70
- if (lease.length === 0 || lease.length > 32) {
71
- throw new Error(`Received invalid lease; expected something with length between 1 and 32, but received '${lease}' with length ${lease.length}`);
72
- }
73
- const encoder = new TextEncoder();
74
- const lease32 = new Uint8Array(32);
75
- lease32.set(encoder.encode(lease), 0);
76
- return lease32;
77
- }
78
- else {
79
- throw new Error(`Unknown lease type received of ${typeof lease}`);
80
- }
49
+ if (lease === null || typeof lease === "undefined") return;
50
+ else if (typeof lease === "object" && lease.constructor === Uint8Array) {
51
+ if (lease.length === 0 || lease.length > 32) throw new Error(`Received invalid lease; expected something with length between 1 and 32, but received bytes with length ${lease.length}`);
52
+ if (lease.length === 32) return lease;
53
+ const lease32 = /* @__PURE__ */ new Uint8Array(32);
54
+ lease32.set(lease, 0);
55
+ return lease32;
56
+ } else if (typeof lease === "string") {
57
+ if (lease.length === 0 || lease.length > 32) throw new Error(`Received invalid lease; expected something with length between 1 and 32, but received '${lease}' with length ${lease.length}`);
58
+ const encoder = new TextEncoder();
59
+ const lease32 = /* @__PURE__ */ new Uint8Array(32);
60
+ lease32.set(encoder.encode(lease), 0);
61
+ return lease32;
62
+ } else throw new Error(`Unknown lease type received of ${typeof lease}`);
81
63
  }
82
64
  /**
83
- * @deprecated Use `algorand.client` to interact with accounts, and use `.addr` to get the address
84
- * and/or move from using `SendTransactionFrom` to `TransactionSignerAccount` and use `.addr` instead.
85
- *
86
- * Returns the public address of the given transaction sender.
87
- * @param sender A transaction sender
88
- * @returns The public address
89
- */
90
- const getSenderAddress = function (sender) {
91
- return typeof sender === 'string' ? sender : 'addr' in sender ? sender.addr.toString() : sender.address().toString();
65
+ * @deprecated Use `algorand.client` to interact with accounts, and use `.addr` to get the address
66
+ * and/or move from using `SendTransactionFrom` to `TransactionSignerAccount` and use `.addr` instead.
67
+ *
68
+ * Returns the public address of the given transaction sender.
69
+ * @param sender A transaction sender
70
+ * @returns The public address
71
+ */
72
+ const getSenderAddress = function(sender) {
73
+ return typeof sender === "string" ? sender : "addr" in sender ? sender.addr.toString() : sender.address().toString();
92
74
  };
93
75
  /**
94
- * @deprecated Use `AlgorandClient` / `TransactionComposer` to construct transactions instead or
95
- * construct an `algosdk.TransactionWithSigner` manually instead.
96
- *
97
- * Given a transaction in a variety of supported formats, returns a TransactionWithSigner object ready to be passed to an
98
- * AtomicTransactionComposer's addTransaction method.
99
- * @param transaction One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the
100
- * signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by
101
- * one of algokit utils' helpers (signer is obtained from the defaultSender parameter)
102
- * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not
103
- * include a signer.
104
- * @returns A TransactionWithSigner object.
105
- */
76
+ * @deprecated Use `AlgorandClient` / `TransactionComposer` to construct transactions instead or
77
+ * construct an `algosdk.TransactionWithSigner` manually instead.
78
+ *
79
+ * Given a transaction in a variety of supported formats, returns a TransactionWithSigner object ready to be passed to an
80
+ * AtomicTransactionComposer's addTransaction method.
81
+ * @param transaction One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the
82
+ * signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by
83
+ * one of algokit utils' helpers (signer is obtained from the defaultSender parameter)
84
+ * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not
85
+ * include a signer.
86
+ * @returns A TransactionWithSigner object.
87
+ */
106
88
  const getTransactionWithSigner = async (transaction, defaultSender) => {
107
- if ('txn' in transaction)
108
- return transaction;
109
- if (defaultSender === undefined)
110
- throw new Error('Default sender must be provided when passing in a transaction object that does not contain its own signer');
111
- return transaction instanceof Promise
112
- ? {
113
- txn: (await transaction).transaction,
114
- signer: getSenderTransactionSigner(defaultSender),
115
- }
116
- : 'transaction' in transaction
117
- ? {
118
- txn: transaction.transaction,
119
- signer: getSenderTransactionSigner(transaction.signer),
120
- }
121
- : {
122
- txn: transaction,
123
- signer: getSenderTransactionSigner(defaultSender),
124
- };
89
+ if ("txn" in transaction) return transaction;
90
+ if (defaultSender === void 0) throw new Error("Default sender must be provided when passing in a transaction object that does not contain its own signer");
91
+ return transaction instanceof Promise ? {
92
+ txn: (await transaction).transaction,
93
+ signer: getSenderTransactionSigner(defaultSender)
94
+ } : "transaction" in transaction ? {
95
+ txn: transaction.transaction,
96
+ signer: getSenderTransactionSigner(transaction.signer)
97
+ } : {
98
+ txn: transaction,
99
+ signer: getSenderTransactionSigner(defaultSender)
100
+ };
125
101
  };
126
102
  const memoize = (fn) => {
127
- const cache = new Map();
128
- const cached = function (val) {
129
- return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val);
130
- };
131
- cached.cache = cache;
132
- return cached;
103
+ const cache = /* @__PURE__ */ new Map();
104
+ const cached = function(val) {
105
+ return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val);
106
+ };
107
+ cached.cache = cache;
108
+ return cached;
133
109
  };
134
110
  /**
135
- * @deprecated Use `TransactionSignerAccount` instead of `SendTransactionFrom` or use
136
- * `algosdk.makeBasicAccountTransactionSigner` / `algosdk.makeLogicSigAccountTransactionSigner`.
137
- *
138
- * Returns a `TransactionSigner` for the given transaction sender.
139
- * This function has memoization, so will return the same transaction signer for a given sender.
140
- * @param sender A transaction sender
141
- * @returns A transaction signer
142
- */
143
- const getSenderTransactionSigner = memoize(function (sender) {
144
- return 'signer' in sender
145
- ? sender.signer
146
- : 'lsig' in sender
147
- ? algosdk.makeLogicSigAccountTransactionSigner(sender)
148
- : algosdk.makeBasicAccountTransactionSigner(sender);
111
+ * @deprecated Use `TransactionSignerAccount` instead of `SendTransactionFrom` or use
112
+ * `algosdk.makeBasicAccountTransactionSigner` / `algosdk.makeLogicSigAccountTransactionSigner`.
113
+ *
114
+ * Returns a `TransactionSigner` for the given transaction sender.
115
+ * This function has memoization, so will return the same transaction signer for a given sender.
116
+ * @param sender A transaction sender
117
+ * @returns A transaction signer
118
+ */
119
+ const getSenderTransactionSigner = memoize(function(sender) {
120
+ return "signer" in sender ? sender.signer : "lsig" in sender ? algosdk.default.makeLogicSigAccountTransactionSigner(sender) : algosdk.default.makeBasicAccountTransactionSigner(sender);
149
121
  });
150
122
  /**
151
- * @deprecated Use `AlgorandClient` / `TransactionComposer` to sign transactions
152
- * or use the relevant underlying `account.signTxn` / `algosdk.signLogicSigTransactionObject`
153
- * / `multiSigAccount.sign` / `TransactionSigner` methods directly.
154
- *
155
- * Signs a single transaction by the given signer.
156
- * @param transaction The transaction to sign
157
- * @param signer The signer to sign
158
- * @returns The signed transaction as a `Uint8Array`
159
- */
123
+ * @deprecated Use `AlgorandClient` / `TransactionComposer` to sign transactions
124
+ * or use the relevant underlying `account.signTxn` / `algosdk.signLogicSigTransactionObject`
125
+ * / `multiSigAccount.sign` / `TransactionSigner` methods directly.
126
+ *
127
+ * Signs a single transaction by the given signer.
128
+ * @param transaction The transaction to sign
129
+ * @param signer The signer to sign
130
+ * @returns The signed transaction as a `Uint8Array`
131
+ */
160
132
  const signTransaction = async (transaction, signer) => {
161
- return 'sk' in signer
162
- ? transaction.signTxn(signer.sk)
163
- : 'lsig' in signer
164
- ? algosdk.signLogicSigTransactionObject(transaction, signer).blob
165
- : 'sign' in signer
166
- ? signer.sign(transaction)
167
- : (await signer.signer([transaction], [0]))[0];
133
+ return "sk" in signer ? transaction.signTxn(signer.sk) : "lsig" in signer ? algosdk.default.signLogicSigTransactionObject(transaction, signer).blob : "sign" in signer ? signer.sign(transaction) : (await signer.signer([transaction], [0]))[0];
168
134
  };
169
135
  /**
170
- * @deprecated Use `AlgorandClient` / `TransactionComposer` to send transactions.
171
- *
172
- * Prepares a transaction for sending and then (if instructed) signs and sends the given transaction to the chain.
173
- *
174
- * @param send The details for the transaction to prepare/send, including:
175
- * * `transaction`: The unsigned transaction
176
- * * `from`: The account to sign the transaction with: either an account with private key loaded or a logic signature account
177
- * * `config`: The sending configuration for this transaction
178
- * @param algod An algod client
179
- *
180
- * @returns An object with transaction (`transaction`) and (if `skipWaiting` is `false` or `undefined`) confirmation (`confirmation`)
181
- */
182
- const sendTransaction = async function (send, algod) {
183
- const { transaction, from, sendParams } = send;
184
- const { skipSending, skipWaiting, fee, maxFee, suppressLog, maxRoundsToWaitForConfirmation, atc } = sendParams ?? {};
185
- controlFees(transaction, { fee, maxFee });
186
- if (atc) {
187
- atc.addTransaction({ txn: transaction, signer: getSenderTransactionSigner(from) });
188
- return { transaction };
189
- }
190
- if (skipSending) {
191
- return { transaction };
192
- }
193
- let txnToSend = transaction;
194
- const populateAppCallResources = sendParams?.populateAppCallResources ?? config.Config.populateAppCallResources;
195
- // Populate resources if the transaction is an appcall and populateAppCallResources wasn't explicitly set to false
196
- if (txnToSend.type === algosdk.TransactionType.appl && populateAppCallResources) {
197
- const newAtc = new AtomicTransactionComposer();
198
- newAtc.addTransaction({ txn: txnToSend, signer: getSenderTransactionSigner(from) });
199
- const atc = await prepareGroupForSending(newAtc, algod, { ...sendParams, populateAppCallResources });
200
- txnToSend = atc.buildGroup()[0].txn;
201
- }
202
- const signedTransaction = await signTransaction(txnToSend, from);
203
- await algod.sendRawTransaction(signedTransaction).do();
204
- config.Config.getLogger(suppressLog).verbose(`Sent transaction ID ${txnToSend.txID()} ${txnToSend.type} from ${getSenderAddress(from)}`);
205
- let confirmation = undefined;
206
- if (!skipWaiting) {
207
- confirmation = await waitForConfirmation(txnToSend.txID(), maxRoundsToWaitForConfirmation ?? 5, algod);
208
- }
209
- return { transaction: txnToSend, confirmation };
136
+ * @deprecated Use `AlgorandClient` / `TransactionComposer` to send transactions.
137
+ *
138
+ * Prepares a transaction for sending and then (if instructed) signs and sends the given transaction to the chain.
139
+ *
140
+ * @param send The details for the transaction to prepare/send, including:
141
+ * * `transaction`: The unsigned transaction
142
+ * * `from`: The account to sign the transaction with: either an account with private key loaded or a logic signature account
143
+ * * `config`: The sending configuration for this transaction
144
+ * @param algod An algod client
145
+ *
146
+ * @returns An object with transaction (`transaction`) and (if `skipWaiting` is `false` or `undefined`) confirmation (`confirmation`)
147
+ */
148
+ const sendTransaction = async function(send, algod) {
149
+ const { transaction, from, sendParams } = send;
150
+ const { skipSending, skipWaiting, fee, maxFee, suppressLog, maxRoundsToWaitForConfirmation, atc } = sendParams ?? {};
151
+ controlFees(transaction, {
152
+ fee,
153
+ maxFee
154
+ });
155
+ if (atc) {
156
+ atc.addTransaction({
157
+ txn: transaction,
158
+ signer: getSenderTransactionSigner(from)
159
+ });
160
+ return { transaction };
161
+ }
162
+ if (skipSending) return { transaction };
163
+ let txnToSend = transaction;
164
+ const populateAppCallResources = sendParams?.populateAppCallResources ?? require_config.Config.populateAppCallResources;
165
+ if (txnToSend.type === algosdk.default.TransactionType.appl && populateAppCallResources) {
166
+ const newAtc = new AtomicTransactionComposer();
167
+ newAtc.addTransaction({
168
+ txn: txnToSend,
169
+ signer: getSenderTransactionSigner(from)
170
+ });
171
+ txnToSend = (await prepareGroupForSending(newAtc, algod, {
172
+ ...sendParams,
173
+ populateAppCallResources
174
+ })).buildGroup()[0].txn;
175
+ }
176
+ const signedTransaction = await signTransaction(txnToSend, from);
177
+ await algod.sendRawTransaction(signedTransaction).do();
178
+ require_config.Config.getLogger(suppressLog).verbose(`Sent transaction ID ${txnToSend.txID()} ${txnToSend.type} from ${getSenderAddress(from)}`);
179
+ let confirmation = void 0;
180
+ if (!skipWaiting) confirmation = await waitForConfirmation(txnToSend.txID(), maxRoundsToWaitForConfirmation ?? 5, algod);
181
+ return {
182
+ transaction: txnToSend,
183
+ confirmation
184
+ };
210
185
  };
211
186
  /**
212
- * Get the execution info of a transaction group for the given ATC
213
- * The function uses the simulate endpoint and depending on the sendParams can return the following:
214
- * - The unnamed resources accessed by the group
215
- * - The unnamed resources accessed by each transaction in the group
216
- * - The required fee delta for each transaction in the group. A positive value indicates a fee deficit, a negative value indicates a surplus.
217
- *
218
- * @param atc The ATC containing the txn group
219
- * @param algod The algod client to use for the simulation
220
- * @param sendParams The send params for the transaction group
221
- * @param additionalAtcContext Additional ATC context used to determine how best to alter transactions in the group
222
- * @returns The execution info for the group
223
- */
187
+ * Get the execution info of a transaction group for the given ATC
188
+ * The function uses the simulate endpoint and depending on the sendParams can return the following:
189
+ * - The unnamed resources accessed by the group
190
+ * - The unnamed resources accessed by each transaction in the group
191
+ * - The required fee delta for each transaction in the group. A positive value indicates a fee deficit, a negative value indicates a surplus.
192
+ *
193
+ * @param atc The ATC containing the txn group
194
+ * @param algod The algod client to use for the simulation
195
+ * @param sendParams The send params for the transaction group
196
+ * @param additionalAtcContext Additional ATC context used to determine how best to alter transactions in the group
197
+ * @returns The execution info for the group
198
+ */
224
199
  async function getGroupExecutionInfo(atc, algod, sendParams, additionalAtcContext) {
225
- const simulateRequest = new algosdk.modelsv2.SimulateRequest({
226
- txnGroups: [],
227
- allowUnnamedResources: true,
228
- allowEmptySignatures: true,
229
- fixSigners: true,
230
- });
231
- const nullSigner = algosdk.makeEmptyTransactionSigner();
232
- const emptySignerAtc = atc.clone();
233
- const appCallIndexesWithoutMaxFees = [];
234
- emptySignerAtc['transactions'].forEach((t, i) => {
235
- t.signer = nullSigner;
236
- if (sendParams.coverAppCallInnerTransactionFees && t.txn.type === algosdk.TransactionType.appl) {
237
- if (!additionalAtcContext?.suggestedParams) {
238
- throw Error(`Please provide additionalAtcContext.suggestedParams when coverAppCallInnerTransactionFees is enabled`);
239
- }
240
- const maxFee = additionalAtcContext?.maxFees?.get(i)?.microAlgo;
241
- if (maxFee === undefined) {
242
- appCallIndexesWithoutMaxFees.push(i);
243
- }
244
- else {
245
- t.txn.fee = maxFee;
246
- }
247
- }
248
- });
249
- if (sendParams.coverAppCallInnerTransactionFees && appCallIndexesWithoutMaxFees.length > 0) {
250
- throw Error(`Please provide a maxFee for each app call transaction when coverAppCallInnerTransactionFees is enabled. Required for transaction ${appCallIndexesWithoutMaxFees.join(', ')}`);
251
- }
252
- const perByteTxnFee = BigInt(additionalAtcContext?.suggestedParams.fee ?? 0n);
253
- const minTxnFee = BigInt(additionalAtcContext?.suggestedParams.minFee ?? 1000n);
254
- const result = await emptySignerAtc.simulate(algod, simulateRequest);
255
- const groupResponse = result.simulateResponse.txnGroups[0];
256
- if (groupResponse.failureMessage) {
257
- if (sendParams.coverAppCallInnerTransactionFees && groupResponse.failureMessage.match(/fee too small/)) {
258
- throw Error(`Fees were too small to resolve execution info via simulate. You may need to increase an app call transaction maxFee.`);
259
- }
260
- throw Error(`Error resolving execution info via simulate in transaction ${groupResponse.failedAt}: ${groupResponse.failureMessage}`);
261
- }
262
- const sortedResources = groupResponse.unnamedResourcesAccessed;
263
- // NOTE: We explicitly want to avoid localeCompare as that can lead to different results in different environments
264
- const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
265
- if (sortedResources) {
266
- sortedResources.accounts?.sort((a, b) => compare(a.toString(), b.toString()));
267
- sortedResources.assets?.sort(compare);
268
- sortedResources.apps?.sort(compare);
269
- sortedResources.boxes?.sort((a, b) => {
270
- const aStr = `${a.app}-${a.name}`;
271
- const bStr = `${b.app}-${b.name}`;
272
- return compare(aStr, bStr);
273
- });
274
- sortedResources.appLocals?.sort((a, b) => {
275
- const aStr = `${a.app}-${a.account}`;
276
- const bStr = `${b.app}-${b.account}`;
277
- return compare(aStr, bStr);
278
- });
279
- sortedResources.assetHoldings?.sort((a, b) => {
280
- const aStr = `${a.asset}-${a.account}`;
281
- const bStr = `${b.asset}-${b.account}`;
282
- return compare(aStr, bStr);
283
- });
284
- }
285
- return {
286
- groupUnnamedResourcesAccessed: sendParams.populateAppCallResources ? sortedResources : undefined,
287
- txns: groupResponse.txnResults.map((txn, i) => {
288
- const originalTxn = atc['transactions'][i].txn;
289
- let requiredFeeDelta = 0n;
290
- if (sendParams.coverAppCallInnerTransactionFees) {
291
- // Min fee calc is lifted from algosdk https://github.com/algorand/js-algorand-sdk/blob/6973ff583b243ddb0632e91f4c0383021430a789/src/transaction.ts#L710
292
- // 75 is the number of bytes added to a txn after signing it
293
- const parentPerByteFee = perByteTxnFee * BigInt(originalTxn.toByte().length + 75);
294
- const parentMinFee = parentPerByteFee < minTxnFee ? minTxnFee : parentPerByteFee;
295
- const parentFeeDelta = parentMinFee - originalTxn.fee;
296
- if (originalTxn.type === algosdk.TransactionType.appl) {
297
- const calculateInnerFeeDelta = (itxns, acc = 0n) => {
298
- // Surplus inner transaction fees do not pool up to the parent transaction.
299
- // Additionally surplus inner transaction fees only pool from sibling transactions that are sent prior to a given inner transaction, hence why we iterate in reverse order.
300
- return itxns.reverse().reduce((acc, itxn) => {
301
- const currentFeeDelta = (itxn.innerTxns && itxn.innerTxns.length > 0 ? calculateInnerFeeDelta(itxn.innerTxns, acc) : acc) +
302
- (minTxnFee - itxn.txn.txn.fee); // Inner transactions don't require per byte fees
303
- return currentFeeDelta < 0n ? 0n : currentFeeDelta;
304
- }, acc);
305
- };
306
- const innerFeeDelta = calculateInnerFeeDelta(txn.txnResult.innerTxns ?? []);
307
- requiredFeeDelta = innerFeeDelta + parentFeeDelta;
308
- }
309
- else {
310
- requiredFeeDelta = parentFeeDelta;
311
- }
312
- }
313
- return {
314
- unnamedResourcesAccessed: sendParams.populateAppCallResources ? txn.unnamedResourcesAccessed : undefined,
315
- requiredFeeDelta,
316
- };
317
- }),
318
- };
200
+ const simulateRequest = new algosdk.default.modelsv2.SimulateRequest({
201
+ txnGroups: [],
202
+ allowUnnamedResources: true,
203
+ allowEmptySignatures: true,
204
+ fixSigners: true
205
+ });
206
+ const nullSigner = algosdk.default.makeEmptyTransactionSigner();
207
+ const emptySignerAtc = atc.clone();
208
+ const appCallIndexesWithoutMaxFees = [];
209
+ emptySignerAtc["transactions"].forEach((t, i) => {
210
+ t.signer = nullSigner;
211
+ if (sendParams.coverAppCallInnerTransactionFees && t.txn.type === algosdk.TransactionType.appl) {
212
+ if (!additionalAtcContext?.suggestedParams) throw Error(`Please provide additionalAtcContext.suggestedParams when coverAppCallInnerTransactionFees is enabled`);
213
+ const maxFee = additionalAtcContext?.maxFees?.get(i)?.microAlgo;
214
+ if (maxFee === void 0) appCallIndexesWithoutMaxFees.push(i);
215
+ else t.txn.fee = maxFee;
216
+ }
217
+ });
218
+ if (sendParams.coverAppCallInnerTransactionFees && appCallIndexesWithoutMaxFees.length > 0) throw Error(`Please provide a maxFee for each app call transaction when coverAppCallInnerTransactionFees is enabled. Required for transaction ${appCallIndexesWithoutMaxFees.join(", ")}`);
219
+ const perByteTxnFee = BigInt(additionalAtcContext?.suggestedParams.fee ?? 0n);
220
+ const minTxnFee = BigInt(additionalAtcContext?.suggestedParams.minFee ?? 1000n);
221
+ const groupResponse = (await emptySignerAtc.simulate(algod, simulateRequest)).simulateResponse.txnGroups[0];
222
+ if (groupResponse.failureMessage) {
223
+ if (sendParams.coverAppCallInnerTransactionFees && groupResponse.failureMessage.match(/fee ([\w.]+\s+)?too small/)) throw Error(`Fees were too small to resolve execution info via simulate. You may need to increase an app call transaction maxFee.`);
224
+ throw Error(`Error resolving execution info via simulate in transaction ${groupResponse.failedAt}: ${groupResponse.failureMessage}`);
225
+ }
226
+ const sortedResources = groupResponse.unnamedResourcesAccessed;
227
+ const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
228
+ if (sortedResources) {
229
+ sortedResources.accounts?.sort((a, b) => compare(a.toString(), b.toString()));
230
+ sortedResources.assets?.sort(compare);
231
+ sortedResources.apps?.sort(compare);
232
+ sortedResources.boxes?.sort((a, b) => {
233
+ const aStr = `${a.app}-${a.name}`;
234
+ const bStr = `${b.app}-${b.name}`;
235
+ return compare(aStr, bStr);
236
+ });
237
+ sortedResources.appLocals?.sort((a, b) => {
238
+ const aStr = `${a.app}-${a.account}`;
239
+ const bStr = `${b.app}-${b.account}`;
240
+ return compare(aStr, bStr);
241
+ });
242
+ sortedResources.assetHoldings?.sort((a, b) => {
243
+ const aStr = `${a.asset}-${a.account}`;
244
+ const bStr = `${b.asset}-${b.account}`;
245
+ return compare(aStr, bStr);
246
+ });
247
+ }
248
+ return {
249
+ groupUnnamedResourcesAccessed: sendParams.populateAppCallResources ? sortedResources : void 0,
250
+ txns: groupResponse.txnResults.map((txn, i) => {
251
+ const originalTxn = atc["transactions"][i].txn;
252
+ let requiredFeeDelta = 0n;
253
+ if (sendParams.coverAppCallInnerTransactionFees) {
254
+ const parentPerByteFee = perByteTxnFee * BigInt(originalTxn.toByte().length + 75);
255
+ const parentFeeDelta = (parentPerByteFee < minTxnFee ? minTxnFee : parentPerByteFee) - originalTxn.fee;
256
+ if (originalTxn.type === algosdk.TransactionType.appl) {
257
+ const calculateInnerFeeDelta = (itxns, acc = 0n) => {
258
+ return itxns.reverse().reduce((acc, itxn) => {
259
+ const currentFeeDelta = (itxn.innerTxns && itxn.innerTxns.length > 0 ? calculateInnerFeeDelta(itxn.innerTxns, acc) : acc) + (minTxnFee - itxn.txn.txn.fee);
260
+ return currentFeeDelta < 0n ? 0n : currentFeeDelta;
261
+ }, acc);
262
+ };
263
+ requiredFeeDelta = calculateInnerFeeDelta(txn.txnResult.innerTxns ?? []) + parentFeeDelta;
264
+ } else requiredFeeDelta = parentFeeDelta;
265
+ }
266
+ return {
267
+ unnamedResourcesAccessed: sendParams.populateAppCallResources ? txn.unnamedResourcesAccessed : void 0,
268
+ requiredFeeDelta
269
+ };
270
+ })
271
+ };
319
272
  }
320
273
  /**
321
- * Take an existing Atomic Transaction Composer and return a new one with the required
322
- * app call resources populated into it
323
- *
324
- * @param algod The algod client to use for the simulation
325
- * @param atc The ATC containing the txn group
326
- * @returns A new ATC with the resources populated into the transactions
327
- *
328
- * @privateRemarks
329
- *
330
- * This entire function will eventually be implemented in simulate upstream in algod. The simulate endpoint will return
331
- * an array of refference arrays for each transaction, so this eventually will eventually just call simulate and set the
332
- * reference arrays in the transactions to the reference arrays returned by simulate.
333
- *
334
- * See https://github.com/algorand/go-algorand/pull/5684
335
- *
336
- */
274
+ * Take an existing Atomic Transaction Composer and return a new one with the required
275
+ * app call resources populated into it
276
+ *
277
+ * @param algod The algod client to use for the simulation
278
+ * @param atc The ATC containing the txn group
279
+ * @returns A new ATC with the resources populated into the transactions
280
+ *
281
+ * @privateRemarks
282
+ *
283
+ * This entire function will eventually be implemented in simulate upstream in algod. The simulate endpoint will return
284
+ * an array of refference arrays for each transaction, so this eventually will eventually just call simulate and set the
285
+ * reference arrays in the transactions to the reference arrays returned by simulate.
286
+ *
287
+ * See https://github.com/algorand/go-algorand/pull/5684
288
+ *
289
+ */
337
290
  async function populateAppCallResources(atc, algod) {
338
- return await prepareGroupForSending(atc, algod, { populateAppCallResources: true });
291
+ return await prepareGroupForSending(atc, algod, { populateAppCallResources: true });
339
292
  }
340
293
  /**
341
- * Take an existing Atomic Transaction Composer and return a new one with changes applied to the transactions
342
- * based on the supplied sendParams to prepare it for sending.
343
- * Please note, that before calling `.execute()` on the returned ATC, you must call `.buildGroup()`.
344
- *
345
- * @param algod The algod client to use for the simulation
346
- * @param atc The ATC containing the txn group
347
- * @param sendParams The send params for the transaction group
348
- * @param additionalAtcContext Additional ATC context used to determine how best to change the transactions in the group
349
- * @returns A new ATC with the changes applied
350
- *
351
- * @privateRemarks
352
- * Parts of this function will eventually be implemented in algod. Namely:
353
- * - Simulate will return information on how to populate reference arrays, see https://github.com/algorand/go-algorand/pull/6015
354
- */
294
+ * Take an existing Atomic Transaction Composer and return a new one with changes applied to the transactions
295
+ * based on the supplied sendParams to prepare it for sending.
296
+ * Please note, that before calling `.execute()` on the returned ATC, you must call `.buildGroup()`.
297
+ *
298
+ * @param algod The algod client to use for the simulation
299
+ * @param atc The ATC containing the txn group
300
+ * @param sendParams The send params for the transaction group
301
+ * @param additionalAtcContext Additional ATC context used to determine how best to change the transactions in the group
302
+ * @returns A new ATC with the changes applied
303
+ *
304
+ * @privateRemarks
305
+ * Parts of this function will eventually be implemented in algod. Namely:
306
+ * - Simulate will return information on how to populate reference arrays, see https://github.com/algorand/go-algorand/pull/6015
307
+ */
355
308
  async function prepareGroupForSending(atc, algod, sendParams, additionalAtcContext) {
356
- const executionInfo = await getGroupExecutionInfo(atc, algod, sendParams, additionalAtcContext);
357
- const group = atc.buildGroup();
358
- const [_, additionalTransactionFees] = sendParams.coverAppCallInnerTransactionFees
359
- ? executionInfo.txns
360
- .map((txn, i) => {
361
- const groupIndex = i;
362
- const txnInGroup = group[groupIndex].txn;
363
- const maxFee = additionalAtcContext?.maxFees?.get(i)?.microAlgo;
364
- const immutableFee = maxFee !== undefined && maxFee === txnInGroup.fee;
365
- // Because we don't alter non app call transaction, they take priority
366
- const priorityMultiplier = txn.requiredFeeDelta > 0n && (immutableFee || txnInGroup.type !== algosdk.TransactionType.appl) ? 1000n : 1n;
367
- return {
368
- ...txn,
369
- groupIndex,
370
- // Measures the priority level of covering the transaction fee using the surplus group fees. The higher the number, the higher the priority.
371
- surplusFeePriorityLevel: txn.requiredFeeDelta > 0n ? txn.requiredFeeDelta * priorityMultiplier : -1n,
372
- };
373
- })
374
- .sort((a, b) => {
375
- return a.surplusFeePriorityLevel > b.surplusFeePriorityLevel ? -1 : a.surplusFeePriorityLevel < b.surplusFeePriorityLevel ? 1 : 0;
376
- })
377
- .reduce((acc, { groupIndex, requiredFeeDelta }) => {
378
- if (requiredFeeDelta > 0n) {
379
- // There is a fee deficit on the transaction
380
- let surplusGroupFees = acc[0];
381
- const additionalTransactionFees = acc[1];
382
- const additionalFeeDelta = requiredFeeDelta - surplusGroupFees;
383
- if (additionalFeeDelta <= 0n) {
384
- // The surplus group fees fully cover the required fee delta
385
- surplusGroupFees = -additionalFeeDelta;
386
- }
387
- else {
388
- // The surplus group fees do not fully cover the required fee delta, use what is available
389
- additionalTransactionFees.set(groupIndex, additionalFeeDelta);
390
- surplusGroupFees = 0n;
391
- }
392
- return [surplusGroupFees, additionalTransactionFees];
393
- }
394
- return acc;
395
- }, [
396
- executionInfo.txns.reduce((acc, { requiredFeeDelta }) => {
397
- if (requiredFeeDelta < 0n) {
398
- return acc + -requiredFeeDelta;
399
- }
400
- return acc;
401
- }, 0n),
402
- new Map(),
403
- ])
404
- : [0n, new Map()];
405
- const appCallHasAccessReferences = (txn) => {
406
- return txn.type === algosdk.TransactionType.appl && txn.applicationCall?.access && txn.applicationCall?.access.length > 0;
407
- };
408
- const indexesWithAccessReferences = [];
409
- executionInfo.txns.forEach(({ unnamedResourcesAccessed: r }, i) => {
410
- // Populate Transaction App Call Resources
411
- if (sendParams.populateAppCallResources && group[i].txn.type === algosdk.TransactionType.appl) {
412
- const hasAccessReferences = appCallHasAccessReferences(group[i].txn);
413
- if (hasAccessReferences && (r || executionInfo.groupUnnamedResourcesAccessed)) {
414
- indexesWithAccessReferences.push(i);
415
- }
416
- if (r && !hasAccessReferences) {
417
- if (r.boxes || r.extraBoxRefs)
418
- throw Error('Unexpected boxes at the transaction level');
419
- if (r.appLocals)
420
- throw Error('Unexpected app local at the transaction level');
421
- if (r.assetHoldings)
422
- throw Error('Unexpected asset holding at the transaction level');
423
- group[i].txn['applicationCall'] = {
424
- ...group[i].txn.applicationCall,
425
- accounts: [...(group[i].txn?.applicationCall?.accounts ?? []), ...(r.accounts ?? [])],
426
- foreignApps: [...(group[i].txn?.applicationCall?.foreignApps ?? []), ...(r.apps ?? [])],
427
- foreignAssets: [...(group[i].txn?.applicationCall?.foreignAssets ?? []), ...(r.assets ?? [])],
428
- boxes: [...(group[i].txn?.applicationCall?.boxes ?? []), ...(r.boxes ?? [])],
429
- };
430
- const accounts = group[i].txn.applicationCall?.accounts?.length ?? 0;
431
- if (accounts > MAX_APP_CALL_ACCOUNT_REFERENCES)
432
- throw Error(`Account reference limit of ${MAX_APP_CALL_ACCOUNT_REFERENCES} exceeded in transaction ${i}`);
433
- const assets = group[i].txn.applicationCall?.foreignAssets?.length ?? 0;
434
- const apps = group[i].txn.applicationCall?.foreignApps?.length ?? 0;
435
- const boxes = group[i].txn.applicationCall?.boxes?.length ?? 0;
436
- if (accounts + assets + apps + boxes > MAX_APP_CALL_FOREIGN_REFERENCES) {
437
- throw Error(`Resource reference limit of ${MAX_APP_CALL_FOREIGN_REFERENCES} exceeded in transaction ${i}`);
438
- }
439
- }
440
- }
441
- // Cover App Call Inner Transaction Fees
442
- if (sendParams.coverAppCallInnerTransactionFees) {
443
- const additionalTransactionFee = additionalTransactionFees.get(i);
444
- if (additionalTransactionFee !== undefined) {
445
- if (group[i].txn.type !== algosdk.TransactionType.appl) {
446
- throw Error(`An additional fee of ${additionalTransactionFee} µALGO is required for non app call transaction ${i}`);
447
- }
448
- const transactionFee = group[i].txn.fee + additionalTransactionFee;
449
- const maxFee = additionalAtcContext?.maxFees?.get(i)?.microAlgo;
450
- if (maxFee === undefined || transactionFee > maxFee) {
451
- throw Error(`Calculated transaction fee ${transactionFee} µALGO is greater than max of ${maxFee ?? 'undefined'} for transaction ${i}`);
452
- }
453
- group[i].txn.fee = transactionFee;
454
- }
455
- }
456
- });
457
- // Populate Group App Call Resources
458
- if (sendParams.populateAppCallResources) {
459
- if (indexesWithAccessReferences.length > 0) {
460
- config.Config.logger.warn(`Resource population will be skipped for transaction indexes ${indexesWithAccessReferences.join(', ')} as they use access references.`);
461
- }
462
- const populateGroupResource = (txns, reference, type) => {
463
- const isApplBelowLimit = (t) => {
464
- if (t.txn.type !== algosdk.TransactionType.appl)
465
- return false;
466
- if (appCallHasAccessReferences(t.txn))
467
- return false;
468
- const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
469
- const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
470
- const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
471
- const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
472
- return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES;
473
- };
474
- // If this is a asset holding or app local, first try to find a transaction that already has the account available
475
- if (type === 'assetHolding' || type === 'appLocal') {
476
- const { account } = reference;
477
- let txnIndex = txns.findIndex((t) => {
478
- if (!isApplBelowLimit(t))
479
- return false;
480
- return (
481
- // account is in the foreign accounts array
482
- t.txn.applicationCall?.accounts?.map((a) => a.toString()).includes(account.toString()) ||
483
- // account is available as an app account
484
- t.txn.applicationCall?.foreignApps?.map((a) => algosdk.getApplicationAddress(a).toString()).includes(account.toString()) ||
485
- // account is available since it's in one of the fields
486
- Object.values(t.txn).some((f) => algosdk.stringifyJSON(f, (_, v) => (v instanceof algosdk.Address ? v.toString() : v))?.includes(account.toString())));
487
- });
488
- if (txnIndex > -1) {
489
- if (type === 'assetHolding') {
490
- const { asset } = reference;
491
- txns[txnIndex].txn['applicationCall'] = {
492
- ...txns[txnIndex].txn.applicationCall,
493
- foreignAssets: [...(txns[txnIndex].txn?.applicationCall?.foreignAssets ?? []), ...[asset]],
494
- };
495
- }
496
- else {
497
- const { app } = reference;
498
- txns[txnIndex].txn['applicationCall'] = {
499
- ...txns[txnIndex].txn.applicationCall,
500
- foreignApps: [...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []), ...[app]],
501
- };
502
- }
503
- return;
504
- }
505
- // Now try to find a txn that already has that app or asset available
506
- txnIndex = txns.findIndex((t) => {
507
- if (!isApplBelowLimit(t))
508
- return false;
509
- // check if there is space in the accounts array
510
- if ((t.txn.applicationCall?.accounts?.length ?? 0) >= MAX_APP_CALL_ACCOUNT_REFERENCES)
511
- return false;
512
- if (type === 'assetHolding') {
513
- const { asset } = reference;
514
- return t.txn.applicationCall?.foreignAssets?.includes(asset);
515
- }
516
- else {
517
- const { app } = reference;
518
- return t.txn.applicationCall?.foreignApps?.includes(app) || t.txn.applicationCall?.appIndex === app;
519
- }
520
- });
521
- if (txnIndex > -1) {
522
- const { account } = reference;
523
- txns[txnIndex].txn['applicationCall'] = {
524
- ...txns[txnIndex].txn.applicationCall,
525
- accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[account]],
526
- };
527
- return;
528
- }
529
- }
530
- // If this is a box, first try to find a transaction that already has the app available
531
- if (type === 'box') {
532
- const { app, name } = reference;
533
- const txnIndex = txns.findIndex((t) => {
534
- if (!isApplBelowLimit(t))
535
- return false;
536
- // If the app is in the foreign array OR the app being called, then we know it's available
537
- return t.txn.applicationCall?.foreignApps?.includes(app) || t.txn.applicationCall?.appIndex === app;
538
- });
539
- if (txnIndex > -1) {
540
- txns[txnIndex].txn['applicationCall'] = {
541
- ...txns[txnIndex].txn.applicationCall,
542
- boxes: [...(txns[txnIndex].txn?.applicationCall?.boxes ?? []), ...[{ appIndex: app, name }]],
543
- };
544
- return;
545
- }
546
- }
547
- // Find the txn index to put the reference(s)
548
- const txnIndex = txns.findIndex((t) => {
549
- if (t.txn.type !== algosdk.TransactionType.appl)
550
- return false;
551
- if (appCallHasAccessReferences(t.txn))
552
- return false;
553
- const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
554
- const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
555
- const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
556
- const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
557
- if (type === 'account')
558
- return accounts < MAX_APP_CALL_ACCOUNT_REFERENCES && accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES;
559
- // If we're adding local state or asset holding, we need space for the acocunt and the other reference
560
- if (type === 'assetHolding' || type === 'appLocal') {
561
- return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES - 1 && accounts < MAX_APP_CALL_ACCOUNT_REFERENCES;
562
- }
563
- // If we're adding a box, we need space for both the box ref and the app ref
564
- if (type === 'box' && BigInt(reference.app) !== BigInt(0)) {
565
- return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES - 1;
566
- }
567
- return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES;
568
- });
569
- if (txnIndex === -1) {
570
- throw Error('No more transactions below reference limit. Add another app call to the group.');
571
- }
572
- if (type === 'account') {
573
- txns[txnIndex].txn['applicationCall'] = {
574
- ...txns[txnIndex].txn.applicationCall,
575
- accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[reference]],
576
- };
577
- }
578
- else if (type === 'app') {
579
- txns[txnIndex].txn['applicationCall'] = {
580
- ...txns[txnIndex].txn.applicationCall,
581
- foreignApps: [
582
- ...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []),
583
- ...[typeof reference === 'bigint' ? reference : BigInt(reference)],
584
- ],
585
- };
586
- }
587
- else if (type === 'box') {
588
- const { app, name } = reference;
589
- txns[txnIndex].txn['applicationCall'] = {
590
- ...txns[txnIndex].txn.applicationCall,
591
- boxes: [...(txns[txnIndex].txn?.applicationCall?.boxes ?? []), ...[{ appIndex: app, name }]],
592
- };
593
- if (app.toString() !== '0') {
594
- txns[txnIndex].txn['applicationCall'] = {
595
- ...txns[txnIndex].txn.applicationCall,
596
- foreignApps: [...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []), ...[app]],
597
- };
598
- }
599
- }
600
- else if (type === 'assetHolding') {
601
- const { asset, account } = reference;
602
- txns[txnIndex].txn['applicationCall'] = {
603
- ...txns[txnIndex].txn.applicationCall,
604
- foreignAssets: [...(txns[txnIndex].txn?.applicationCall?.foreignAssets ?? []), ...[asset]],
605
- accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[account]],
606
- };
607
- }
608
- else if (type === 'appLocal') {
609
- const { app, account } = reference;
610
- txns[txnIndex].txn['applicationCall'] = {
611
- ...txns[txnIndex].txn.applicationCall,
612
- foreignApps: [...(txns[txnIndex].txn?.applicationCall?.foreignApps ?? []), ...[app]],
613
- accounts: [...(txns[txnIndex].txn?.applicationCall?.accounts ?? []), ...[account]],
614
- };
615
- }
616
- else if (type === 'asset') {
617
- txns[txnIndex].txn['applicationCall'] = {
618
- ...txns[txnIndex].txn.applicationCall,
619
- foreignAssets: [
620
- ...(txns[txnIndex].txn?.applicationCall?.foreignAssets ?? []),
621
- ...[typeof reference === 'bigint' ? reference : BigInt(reference)],
622
- ],
623
- };
624
- }
625
- };
626
- const g = executionInfo.groupUnnamedResourcesAccessed;
627
- if (g) {
628
- // Do cross-reference resources first because they are the most restrictive in terms
629
- // of which transactions can be used
630
- g.appLocals?.forEach((a) => {
631
- populateGroupResource(group, a, 'appLocal');
632
- // Remove resources from the group if we're adding them here
633
- g.accounts = g.accounts?.filter((acc) => acc !== a.account);
634
- g.apps = g.apps?.filter((app) => BigInt(app) !== BigInt(a.app));
635
- });
636
- g.assetHoldings?.forEach((a) => {
637
- populateGroupResource(group, a, 'assetHolding');
638
- // Remove resources from the group if we're adding them here
639
- g.accounts = g.accounts?.filter((acc) => acc !== a.account);
640
- g.assets = g.assets?.filter((asset) => BigInt(asset) !== BigInt(a.asset));
641
- });
642
- // Do accounts next because the account limit is 4
643
- g.accounts?.forEach((a) => {
644
- populateGroupResource(group, a, 'account');
645
- });
646
- g.boxes?.forEach((b) => {
647
- populateGroupResource(group, b, 'box');
648
- // Remove apps as resource from the group if we're adding it here
649
- g.apps = g.apps?.filter((app) => BigInt(app) !== BigInt(b.app));
650
- });
651
- g.assets?.forEach((a) => {
652
- populateGroupResource(group, a, 'asset');
653
- });
654
- g.apps?.forEach((a) => {
655
- populateGroupResource(group, a, 'app');
656
- });
657
- if (g.extraBoxRefs) {
658
- for (let i = 0; i < g.extraBoxRefs; i += 1) {
659
- const ref = new algosdk.modelsv2.BoxReference({ app: 0, name: new Uint8Array(0) });
660
- populateGroupResource(group, ref, 'box');
661
- }
662
- }
663
- }
664
- }
665
- const newAtc = new algosdk.AtomicTransactionComposer();
666
- group.forEach((t) => {
667
- t.txn.group = undefined;
668
- newAtc.addTransaction(t);
669
- });
670
- newAtc['methodCalls'] = atc['methodCalls'];
671
- return newAtc;
309
+ const executionInfo = await getGroupExecutionInfo(atc, algod, sendParams, additionalAtcContext);
310
+ const group = atc.buildGroup();
311
+ const [_, additionalTransactionFees] = sendParams.coverAppCallInnerTransactionFees ? executionInfo.txns.map((txn, i) => {
312
+ const groupIndex = i;
313
+ const txnInGroup = group[groupIndex].txn;
314
+ const maxFee = additionalAtcContext?.maxFees?.get(i)?.microAlgo;
315
+ const priorityMultiplier = txn.requiredFeeDelta > 0n && (maxFee !== void 0 && maxFee === txnInGroup.fee || txnInGroup.type !== algosdk.default.TransactionType.appl) ? 1000n : 1n;
316
+ return {
317
+ ...txn,
318
+ groupIndex,
319
+ surplusFeePriorityLevel: txn.requiredFeeDelta > 0n ? txn.requiredFeeDelta * priorityMultiplier : -1n
320
+ };
321
+ }).sort((a, b) => {
322
+ return a.surplusFeePriorityLevel > b.surplusFeePriorityLevel ? -1 : a.surplusFeePriorityLevel < b.surplusFeePriorityLevel ? 1 : 0;
323
+ }).reduce((acc, { groupIndex, requiredFeeDelta }) => {
324
+ if (requiredFeeDelta > 0n) {
325
+ let surplusGroupFees = acc[0];
326
+ const additionalTransactionFees = acc[1];
327
+ const additionalFeeDelta = requiredFeeDelta - surplusGroupFees;
328
+ if (additionalFeeDelta <= 0n) surplusGroupFees = -additionalFeeDelta;
329
+ else {
330
+ additionalTransactionFees.set(groupIndex, additionalFeeDelta);
331
+ surplusGroupFees = 0n;
332
+ }
333
+ return [surplusGroupFees, additionalTransactionFees];
334
+ }
335
+ return acc;
336
+ }, [executionInfo.txns.reduce((acc, { requiredFeeDelta }) => {
337
+ if (requiredFeeDelta < 0n) return acc + -requiredFeeDelta;
338
+ return acc;
339
+ }, 0n), /* @__PURE__ */ new Map()]) : [0n, /* @__PURE__ */ new Map()];
340
+ const appCallHasAccessReferences = (txn) => {
341
+ return txn.type === algosdk.TransactionType.appl && txn.applicationCall?.access && txn.applicationCall?.access.length > 0;
342
+ };
343
+ const indexesWithAccessReferences = [];
344
+ executionInfo.txns.forEach(({ unnamedResourcesAccessed: r }, i) => {
345
+ if (sendParams.populateAppCallResources && group[i].txn.type === algosdk.TransactionType.appl) {
346
+ const hasAccessReferences = appCallHasAccessReferences(group[i].txn);
347
+ if (hasAccessReferences && (r || executionInfo.groupUnnamedResourcesAccessed)) indexesWithAccessReferences.push(i);
348
+ if (r && !hasAccessReferences) {
349
+ if (r.boxes || r.extraBoxRefs) throw Error("Unexpected boxes at the transaction level");
350
+ if (r.appLocals) throw Error("Unexpected app local at the transaction level");
351
+ if (r.assetHoldings) throw Error("Unexpected asset holding at the transaction level");
352
+ group[i].txn["applicationCall"] = {
353
+ ...group[i].txn.applicationCall,
354
+ accounts: [...group[i].txn?.applicationCall?.accounts ?? [], ...r.accounts ?? []],
355
+ foreignApps: [...group[i].txn?.applicationCall?.foreignApps ?? [], ...r.apps ?? []],
356
+ foreignAssets: [...group[i].txn?.applicationCall?.foreignAssets ?? [], ...r.assets ?? []],
357
+ boxes: [...group[i].txn?.applicationCall?.boxes ?? [], ...r.boxes ?? []]
358
+ };
359
+ const accounts = group[i].txn.applicationCall?.accounts?.length ?? 0;
360
+ if (accounts > 8) throw Error(`Account reference limit of 8 exceeded in transaction ${i}`);
361
+ const assets = group[i].txn.applicationCall?.foreignAssets?.length ?? 0;
362
+ const apps = group[i].txn.applicationCall?.foreignApps?.length ?? 0;
363
+ const boxes = group[i].txn.applicationCall?.boxes?.length ?? 0;
364
+ if (accounts + assets + apps + boxes > 8) throw Error(`Resource reference limit of 8 exceeded in transaction ${i}`);
365
+ }
366
+ }
367
+ if (sendParams.coverAppCallInnerTransactionFees) {
368
+ const additionalTransactionFee = additionalTransactionFees.get(i);
369
+ if (additionalTransactionFee !== void 0) {
370
+ if (group[i].txn.type !== algosdk.default.TransactionType.appl) throw Error(`An additional fee of ${additionalTransactionFee} µALGO is required for non app call transaction ${i}`);
371
+ const transactionFee = group[i].txn.fee + additionalTransactionFee;
372
+ const maxFee = additionalAtcContext?.maxFees?.get(i)?.microAlgo;
373
+ if (maxFee === void 0 || transactionFee > maxFee) throw Error(`Calculated transaction fee ${transactionFee} µALGO is greater than max of ${maxFee ?? "undefined"} for transaction ${i}`);
374
+ group[i].txn.fee = transactionFee;
375
+ }
376
+ }
377
+ });
378
+ if (sendParams.populateAppCallResources) {
379
+ if (indexesWithAccessReferences.length > 0) require_config.Config.logger.warn(`Resource population will be skipped for transaction indexes ${indexesWithAccessReferences.join(", ")} as they use access references.`);
380
+ const populateGroupResource = (txns, reference, type) => {
381
+ const isApplBelowLimit = (t) => {
382
+ if (t.txn.type !== algosdk.default.TransactionType.appl) return false;
383
+ if (appCallHasAccessReferences(t.txn)) return false;
384
+ const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
385
+ const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
386
+ const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
387
+ const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
388
+ return accounts + assets + apps + boxes < 8;
389
+ };
390
+ if (type === "assetHolding" || type === "appLocal") {
391
+ const { account } = reference;
392
+ let txnIndex = txns.findIndex((t) => {
393
+ if (!isApplBelowLimit(t)) return false;
394
+ return t.txn.applicationCall?.accounts?.map((a) => a.toString()).includes(account.toString()) || t.txn.applicationCall?.foreignApps?.map((a) => algosdk.default.getApplicationAddress(a).toString()).includes(account.toString()) || Object.values(t.txn).some((f) => (0, algosdk.stringifyJSON)(f, (_, v) => v instanceof algosdk.Address ? v.toString() : v)?.includes(account.toString()));
395
+ });
396
+ if (txnIndex > -1) {
397
+ if (type === "assetHolding") {
398
+ const { asset } = reference;
399
+ txns[txnIndex].txn["applicationCall"] = {
400
+ ...txns[txnIndex].txn.applicationCall,
401
+ foreignAssets: [...txns[txnIndex].txn?.applicationCall?.foreignAssets ?? [], ...[asset]]
402
+ };
403
+ } else {
404
+ const { app } = reference;
405
+ txns[txnIndex].txn["applicationCall"] = {
406
+ ...txns[txnIndex].txn.applicationCall,
407
+ foreignApps: [...txns[txnIndex].txn?.applicationCall?.foreignApps ?? [], ...[app]]
408
+ };
409
+ }
410
+ return;
411
+ }
412
+ txnIndex = txns.findIndex((t) => {
413
+ if (!isApplBelowLimit(t)) return false;
414
+ if ((t.txn.applicationCall?.accounts?.length ?? 0) >= 8) return false;
415
+ if (type === "assetHolding") {
416
+ const { asset } = reference;
417
+ return t.txn.applicationCall?.foreignAssets?.includes(asset);
418
+ } else {
419
+ const { app } = reference;
420
+ return t.txn.applicationCall?.foreignApps?.includes(app) || t.txn.applicationCall?.appIndex === app;
421
+ }
422
+ });
423
+ if (txnIndex > -1) {
424
+ const { account } = reference;
425
+ txns[txnIndex].txn["applicationCall"] = {
426
+ ...txns[txnIndex].txn.applicationCall,
427
+ accounts: [...txns[txnIndex].txn?.applicationCall?.accounts ?? [], ...[account]]
428
+ };
429
+ return;
430
+ }
431
+ }
432
+ if (type === "box") {
433
+ const { app, name } = reference;
434
+ const txnIndex = txns.findIndex((t) => {
435
+ if (!isApplBelowLimit(t)) return false;
436
+ return t.txn.applicationCall?.foreignApps?.includes(app) || t.txn.applicationCall?.appIndex === app;
437
+ });
438
+ if (txnIndex > -1) {
439
+ txns[txnIndex].txn["applicationCall"] = {
440
+ ...txns[txnIndex].txn.applicationCall,
441
+ boxes: [...txns[txnIndex].txn?.applicationCall?.boxes ?? [], ...[{
442
+ appIndex: app,
443
+ name
444
+ }]]
445
+ };
446
+ return;
447
+ }
448
+ }
449
+ const txnIndex = txns.findIndex((t) => {
450
+ if (t.txn.type !== algosdk.default.TransactionType.appl) return false;
451
+ if (appCallHasAccessReferences(t.txn)) return false;
452
+ const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
453
+ const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
454
+ const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
455
+ const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
456
+ if (type === "account") return accounts < 8 && accounts + assets + apps + boxes < 8;
457
+ if (type === "assetHolding" || type === "appLocal") return accounts + assets + apps + boxes < 7 && accounts < 8;
458
+ if (type === "box" && BigInt(reference.app) !== BigInt(0)) return accounts + assets + apps + boxes < 7;
459
+ return accounts + assets + apps + boxes < 8;
460
+ });
461
+ if (txnIndex === -1) throw Error("No more transactions below reference limit. Add another app call to the group.");
462
+ if (type === "account") txns[txnIndex].txn["applicationCall"] = {
463
+ ...txns[txnIndex].txn.applicationCall,
464
+ accounts: [...txns[txnIndex].txn?.applicationCall?.accounts ?? [], ...[reference]]
465
+ };
466
+ else if (type === "app") txns[txnIndex].txn["applicationCall"] = {
467
+ ...txns[txnIndex].txn.applicationCall,
468
+ foreignApps: [...txns[txnIndex].txn?.applicationCall?.foreignApps ?? [], ...[typeof reference === "bigint" ? reference : BigInt(reference)]]
469
+ };
470
+ else if (type === "box") {
471
+ const { app, name } = reference;
472
+ txns[txnIndex].txn["applicationCall"] = {
473
+ ...txns[txnIndex].txn.applicationCall,
474
+ boxes: [...txns[txnIndex].txn?.applicationCall?.boxes ?? [], ...[{
475
+ appIndex: app,
476
+ name
477
+ }]]
478
+ };
479
+ if (app.toString() !== "0") txns[txnIndex].txn["applicationCall"] = {
480
+ ...txns[txnIndex].txn.applicationCall,
481
+ foreignApps: [...txns[txnIndex].txn?.applicationCall?.foreignApps ?? [], ...[app]]
482
+ };
483
+ } else if (type === "assetHolding") {
484
+ const { asset, account } = reference;
485
+ txns[txnIndex].txn["applicationCall"] = {
486
+ ...txns[txnIndex].txn.applicationCall,
487
+ foreignAssets: [...txns[txnIndex].txn?.applicationCall?.foreignAssets ?? [], ...[asset]],
488
+ accounts: [...txns[txnIndex].txn?.applicationCall?.accounts ?? [], ...[account]]
489
+ };
490
+ } else if (type === "appLocal") {
491
+ const { app, account } = reference;
492
+ txns[txnIndex].txn["applicationCall"] = {
493
+ ...txns[txnIndex].txn.applicationCall,
494
+ foreignApps: [...txns[txnIndex].txn?.applicationCall?.foreignApps ?? [], ...[app]],
495
+ accounts: [...txns[txnIndex].txn?.applicationCall?.accounts ?? [], ...[account]]
496
+ };
497
+ } else if (type === "asset") txns[txnIndex].txn["applicationCall"] = {
498
+ ...txns[txnIndex].txn.applicationCall,
499
+ foreignAssets: [...txns[txnIndex].txn?.applicationCall?.foreignAssets ?? [], ...[typeof reference === "bigint" ? reference : BigInt(reference)]]
500
+ };
501
+ };
502
+ const g = executionInfo.groupUnnamedResourcesAccessed;
503
+ if (g) {
504
+ g.appLocals?.forEach((a) => {
505
+ populateGroupResource(group, a, "appLocal");
506
+ g.accounts = g.accounts?.filter((acc) => acc !== a.account);
507
+ g.apps = g.apps?.filter((app) => BigInt(app) !== BigInt(a.app));
508
+ });
509
+ g.assetHoldings?.forEach((a) => {
510
+ populateGroupResource(group, a, "assetHolding");
511
+ g.accounts = g.accounts?.filter((acc) => acc !== a.account);
512
+ g.assets = g.assets?.filter((asset) => BigInt(asset) !== BigInt(a.asset));
513
+ });
514
+ g.accounts?.forEach((a) => {
515
+ populateGroupResource(group, a, "account");
516
+ });
517
+ g.boxes?.forEach((b) => {
518
+ populateGroupResource(group, b, "box");
519
+ g.apps = g.apps?.filter((app) => BigInt(app) !== BigInt(b.app));
520
+ });
521
+ g.assets?.forEach((a) => {
522
+ populateGroupResource(group, a, "asset");
523
+ });
524
+ g.apps?.forEach((a) => {
525
+ populateGroupResource(group, a, "app");
526
+ });
527
+ if (g.extraBoxRefs) for (let i = 0; i < g.extraBoxRefs; i += 1) populateGroupResource(group, new algosdk.default.modelsv2.BoxReference({
528
+ app: 0,
529
+ name: /* @__PURE__ */ new Uint8Array(0)
530
+ }), "box");
531
+ }
532
+ }
533
+ const newAtc = new algosdk.default.AtomicTransactionComposer();
534
+ group.forEach((t) => {
535
+ t.txn.group = void 0;
536
+ newAtc.addTransaction(t);
537
+ });
538
+ newAtc["methodCalls"] = atc["methodCalls"];
539
+ return newAtc;
672
540
  }
673
541
  /**
674
- * Signs and sends transactions that have been collected by an `AtomicTransactionComposer`.
675
- * @param atcSend The parameters controlling the send, including `atc` The `AtomicTransactionComposer` and params to control send behaviour
676
- * @param algod An algod client
677
- * @returns An object with transaction IDs, transactions, group transaction ID (`groupTransactionId`) if more than 1 transaction sent, and (if `skipWaiting` is `false` or unset) confirmation (`confirmation`)
678
- */
679
- const sendAtomicTransactionComposer = async function (atcSend, algod) {
680
- const { atc: givenAtc, sendParams, additionalAtcContext, ...executeParams } = atcSend;
681
- let atc;
682
- atc = givenAtc;
683
- try {
684
- const transactionsWithSigner = atc.buildGroup();
685
- // If populateAppCallResources is true OR if populateAppCallResources is undefined and there are app calls, then populate resources
686
- const populateAppCallResources = executeParams?.populateAppCallResources ?? sendParams?.populateAppCallResources ?? config.Config.populateAppCallResources;
687
- const coverAppCallInnerTransactionFees = executeParams?.coverAppCallInnerTransactionFees;
688
- if ((populateAppCallResources || coverAppCallInnerTransactionFees) &&
689
- transactionsWithSigner.map((t) => t.txn.type).includes(algosdk.TransactionType.appl)) {
690
- atc = await prepareGroupForSending(givenAtc, algod, { ...executeParams, populateAppCallResources, coverAppCallInnerTransactionFees }, additionalAtcContext);
691
- }
692
- // atc.buildGroup() is needed to ensure that any changes made by prepareGroupForSending are reflected and the group id is set
693
- const transactionsToSend = atc.buildGroup().map((t) => {
694
- return t.txn;
695
- });
696
- let groupId = undefined;
697
- if (transactionsToSend.length > 1) {
698
- groupId = transactionsToSend[0].group ? buffer.Buffer.from(transactionsToSend[0].group).toString('base64') : '';
699
- config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Sending group of ${transactionsToSend.length} transactions (${groupId})`, {
700
- transactionsToSend,
701
- });
702
- config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).debug(`Transaction IDs (${groupId})`, transactionsToSend.map((t) => t.txID()));
703
- }
704
- if (config.Config.debug && config.Config.traceAll) {
705
- // Emit the simulate response for use with AlgoKit AVM debugger
706
- const simulateResponse = await performAtomicTransactionComposerSimulate.performAtomicTransactionComposerSimulate(atc, algod);
707
- await config.Config.events.emitAsync(types_lifecycleEvents.EventType.TxnGroupSimulated, {
708
- simulateResponse,
709
- });
710
- }
711
- const result = await atc.execute(algod, executeParams?.maxRoundsToWaitForConfirmation ?? sendParams?.maxRoundsToWaitForConfirmation ?? 5);
712
- if (transactionsToSend.length > 1) {
713
- config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Group transaction (${groupId}) sent with ${transactionsToSend.length} transactions`);
714
- }
715
- else {
716
- config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Sent transaction ID ${transactionsToSend[0].txID()} ${transactionsToSend[0].type} from ${transactionsToSend[0].sender.toString()}`);
717
- }
718
- let confirmations = undefined;
719
- if (!sendParams?.skipWaiting) {
720
- confirmations = await Promise.all(transactionsToSend.map(async (t) => await algod.pendingTransactionInformation(t.txID()).do()));
721
- }
722
- const methodCalls = [...atc['methodCalls'].values()];
723
- return {
724
- groupId,
725
- confirmations,
726
- txIds: transactionsToSend.map((t) => t.txID()),
727
- transactions: transactionsToSend,
728
- returns: result.methodResults.map((r, i) => getABIReturnValue(r, methodCalls[i].returns.type)),
729
- };
730
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
731
- }
732
- catch (e) {
733
- // Create a new error object so the stack trace is correct (algosdk throws an error with a more limited stack trace)
734
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
735
- const err = new Error(typeof e === 'object' ? e?.message : 'Received error executing Atomic Transaction Composer');
736
- err.cause = e;
737
- if (typeof e === 'object') {
738
- // Remove headers as it doesn't have anything useful.
739
- delete e.response?.headers;
740
- err.response = e.response;
741
- // body property very noisy
742
- if (e.response && 'body' in e.response)
743
- delete err.response.body;
744
- err.name = e.name;
745
- }
746
- if (config.Config.debug && typeof e === 'object') {
747
- err.traces = [];
748
- config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).error('Received error executing Atomic Transaction Composer and debug flag enabled; attempting simulation to get more information', err);
749
- const simulate = await performAtomicTransactionComposerSimulate.performAtomicTransactionComposerSimulate(atc, algod);
750
- if (config.Config.debug && !config.Config.traceAll) {
751
- // Emit the event only if traceAll: false, as it should have already been emitted above
752
- await config.Config.events.emitAsync(types_lifecycleEvents.EventType.TxnGroupSimulated, {
753
- simulateResponse: simulate,
754
- });
755
- }
756
- if (simulate && simulate.txnGroups[0].failedAt) {
757
- for (const txn of simulate.txnGroups[0].txnResults) {
758
- err.traces.push({
759
- trace: txn.execTrace?.toEncodingData(),
760
- appBudget: txn.appBudgetConsumed,
761
- logicSigBudget: txn.logicSigBudgetConsumed,
762
- logs: txn.txnResult.logs,
763
- message: simulate.txnGroups[0].failureMessage,
764
- });
765
- }
766
- }
767
- }
768
- else {
769
- config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).error('Received error executing Atomic Transaction Composer, for more information enable the debug flag', err);
770
- }
771
- // Attach the sent transactions so we can use them in error transformers
772
- err.sentTransactions = atc.buildGroup().map((t) => t.txn);
773
- throw err;
774
- }
542
+ * Signs and sends transactions that have been collected by an `AtomicTransactionComposer`.
543
+ * @param atcSend The parameters controlling the send, including `atc` The `AtomicTransactionComposer` and params to control send behaviour
544
+ * @param algod An algod client
545
+ * @returns An object with transaction IDs, transactions, group transaction ID (`groupTransactionId`) if more than 1 transaction sent, and (if `skipWaiting` is `false` or unset) confirmation (`confirmation`)
546
+ */
547
+ const sendAtomicTransactionComposer = async function(atcSend, algod) {
548
+ const { atc: givenAtc, sendParams, additionalAtcContext, ...executeParams } = atcSend;
549
+ let atc;
550
+ atc = givenAtc;
551
+ try {
552
+ const transactionsWithSigner = atc.buildGroup();
553
+ const populateAppCallResources = executeParams?.populateAppCallResources ?? sendParams?.populateAppCallResources ?? require_config.Config.populateAppCallResources;
554
+ const coverAppCallInnerTransactionFees = executeParams?.coverAppCallInnerTransactionFees;
555
+ if ((populateAppCallResources || coverAppCallInnerTransactionFees) && transactionsWithSigner.map((t) => t.txn.type).includes(algosdk.default.TransactionType.appl)) atc = await prepareGroupForSending(givenAtc, algod, {
556
+ ...executeParams,
557
+ populateAppCallResources,
558
+ coverAppCallInnerTransactionFees
559
+ }, additionalAtcContext);
560
+ const transactionsToSend = atc.buildGroup().map((t) => {
561
+ return t.txn;
562
+ });
563
+ let groupId = void 0;
564
+ if (transactionsToSend.length > 1) {
565
+ groupId = transactionsToSend[0].group ? buffer.Buffer.from(transactionsToSend[0].group).toString("base64") : "";
566
+ require_config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Sending group of ${transactionsToSend.length} transactions (${groupId})`, { transactionsToSend });
567
+ require_config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).debug(`Transaction IDs (${groupId})`, transactionsToSend.map((t) => t.txID()));
568
+ }
569
+ if (require_config.Config.debug && require_config.Config.traceAll) {
570
+ const simulateResponse = await require_perform_atomic_transaction_composer_simulate.performAtomicTransactionComposerSimulate(atc, algod);
571
+ await require_config.Config.events.emitAsync("TxnGroupSimulated", { simulateResponse });
572
+ }
573
+ const result = await atc.execute(algod, executeParams?.maxRoundsToWaitForConfirmation ?? sendParams?.maxRoundsToWaitForConfirmation ?? 5);
574
+ if (transactionsToSend.length > 1) require_config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Group transaction (${groupId}) sent with ${transactionsToSend.length} transactions`);
575
+ else require_config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).verbose(`Sent transaction ID ${transactionsToSend[0].txID()} ${transactionsToSend[0].type} from ${transactionsToSend[0].sender.toString()}`);
576
+ let confirmations = void 0;
577
+ if (!sendParams?.skipWaiting) confirmations = await Promise.all(transactionsToSend.map(async (t) => await algod.pendingTransactionInformation(t.txID()).do()));
578
+ const methodCalls = [...atc["methodCalls"].values()];
579
+ return {
580
+ groupId,
581
+ confirmations,
582
+ txIds: transactionsToSend.map((t) => t.txID()),
583
+ transactions: transactionsToSend,
584
+ returns: result.methodResults.map((r, i) => getABIReturnValue(r, methodCalls[i].returns.type))
585
+ };
586
+ } catch (e) {
587
+ const err = new Error(typeof e === "object" ? e?.message : "Received error executing Atomic Transaction Composer");
588
+ err.cause = e;
589
+ if (typeof e === "object") {
590
+ delete e.response?.headers;
591
+ err.response = e.response;
592
+ if (e.response && "body" in e.response) delete err.response.body;
593
+ err.name = e.name;
594
+ }
595
+ if (require_config.Config.debug && typeof e === "object") {
596
+ err.traces = [];
597
+ require_config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).error("Received error executing Atomic Transaction Composer and debug flag enabled; attempting simulation to get more information", err);
598
+ const simulate = await require_perform_atomic_transaction_composer_simulate.performAtomicTransactionComposerSimulate(atc, algod);
599
+ if (require_config.Config.debug && !require_config.Config.traceAll) await require_config.Config.events.emitAsync("TxnGroupSimulated", { simulateResponse: simulate });
600
+ if (simulate && simulate.txnGroups[0].failedAt) for (const txn of simulate.txnGroups[0].txnResults) err.traces.push({
601
+ trace: txn.execTrace?.toEncodingData(),
602
+ appBudget: txn.appBudgetConsumed,
603
+ logicSigBudget: txn.logicSigBudgetConsumed,
604
+ logs: txn.txnResult.logs,
605
+ message: simulate.txnGroups[0].failureMessage
606
+ });
607
+ } else require_config.Config.getLogger(executeParams?.suppressLog ?? sendParams?.suppressLog).error("Received error executing Atomic Transaction Composer, for more information enable the debug flag", err);
608
+ err.sentTransactions = atc.buildGroup().map((t) => t.txn);
609
+ throw err;
610
+ }
775
611
  };
776
612
  /**
777
- * Takes an algosdk `ABIResult` and converts it to an `ABIReturn`.
778
- * Converts `bigint`'s for Uint's < 64 to `number` for easier use.
779
- * @param result The `ABIReturn`
780
- */
613
+ * Takes an algosdk `ABIResult` and converts it to an `ABIReturn`.
614
+ * Converts `bigint`'s for Uint's < 64 to `number` for easier use.
615
+ * @param result The `ABIReturn`
616
+ */
781
617
  function getABIReturnValue(result, type) {
782
- if (result.decodeError) {
783
- return {
784
- decodeError: result.decodeError,
785
- };
786
- }
787
- const returnValue = util.convertAbiByteArrays(result.returnValue !== undefined && result.method.returns.type !== 'void'
788
- ? util.convertABIDecodedBigIntToNumber(result.returnValue, result.method.returns.type)
789
- : result.returnValue, type);
790
- return {
791
- method: result.method,
792
- rawReturnValue: result.rawReturnValue,
793
- decodeError: undefined,
794
- returnValue,
795
- };
618
+ if (result.decodeError) return { decodeError: result.decodeError };
619
+ const returnValue = require_util.convertAbiByteArrays(result.returnValue !== void 0 && result.method.returns.type !== "void" ? require_util.convertABIDecodedBigIntToNumber(result.returnValue, result.method.returns.type) : result.returnValue, type);
620
+ return {
621
+ method: result.method,
622
+ rawReturnValue: result.rawReturnValue,
623
+ decodeError: void 0,
624
+ returnValue
625
+ };
796
626
  }
797
627
  /**
798
- * @deprecated Use `TransactionComposer` (`algorand.newGroup()`) or `AtomicTransactionComposer` to construct and send group transactions instead.
799
- *
800
- * Signs and sends a group of [up to 16](https://dev.algorand.co/concepts/transactions/atomic-txn-groups/#create-transactions) transactions to the chain
801
- *
802
- * @param groupSend The group details to send, with:
803
- * * `transactions`: The array of transactions to send along with their signing account
804
- * * `sendParams`: The parameters to dictate how the group is sent
805
- * @param algod An algod client
806
- * @returns An object with transaction IDs, transactions, group transaction ID (`groupTransactionId`) if more than 1 transaction sent, and (if `skipWaiting` is `false` or unset) confirmation (`confirmation`)
807
- */
808
- const sendGroupOfTransactions = async function (groupSend, algod) {
809
- const { transactions, signer, sendParams } = groupSend;
810
- const defaultTransactionSigner = signer ? getSenderTransactionSigner(signer) : undefined;
811
- const transactionsWithSigner = await Promise.all(transactions.map(async (t) => {
812
- if ('signer' in t)
813
- return {
814
- txn: t.transaction,
815
- signer: getSenderTransactionSigner(t.signer),
816
- sender: t.signer,
817
- };
818
- const txn = 'then' in t ? (await t).transaction : t;
819
- if (!signer) {
820
- throw new Error(`Attempt to send transaction ${txn.txID()} as part of a group transaction, but no signer parameter was provided.`);
821
- }
822
- return {
823
- txn,
824
- signer: defaultTransactionSigner,
825
- sender: signer,
826
- };
827
- }));
828
- const atc = new AtomicTransactionComposer();
829
- transactionsWithSigner.forEach((txn) => atc.addTransaction(txn));
830
- return (await sendAtomicTransactionComposer({ atc, sendParams }, algod));
628
+ * @deprecated Use `TransactionComposer` (`algorand.newGroup()`) or `AtomicTransactionComposer` to construct and send group transactions instead.
629
+ *
630
+ * Signs and sends a group of [up to 16](https://dev.algorand.co/concepts/transactions/atomic-txn-groups/#create-transactions) transactions to the chain
631
+ *
632
+ * @param groupSend The group details to send, with:
633
+ * * `transactions`: The array of transactions to send along with their signing account
634
+ * * `sendParams`: The parameters to dictate how the group is sent
635
+ * @param algod An algod client
636
+ * @returns An object with transaction IDs, transactions, group transaction ID (`groupTransactionId`) if more than 1 transaction sent, and (if `skipWaiting` is `false` or unset) confirmation (`confirmation`)
637
+ */
638
+ const sendGroupOfTransactions = async function(groupSend, algod) {
639
+ const { transactions, signer, sendParams } = groupSend;
640
+ const defaultTransactionSigner = signer ? getSenderTransactionSigner(signer) : void 0;
641
+ const transactionsWithSigner = await Promise.all(transactions.map(async (t) => {
642
+ if ("signer" in t) return {
643
+ txn: t.transaction,
644
+ signer: getSenderTransactionSigner(t.signer),
645
+ sender: t.signer
646
+ };
647
+ const txn = "then" in t ? (await t).transaction : t;
648
+ if (!signer) throw new Error(`Attempt to send transaction ${txn.txID()} as part of a group transaction, but no signer parameter was provided.`);
649
+ return {
650
+ txn,
651
+ signer: defaultTransactionSigner,
652
+ sender: signer
653
+ };
654
+ }));
655
+ const atc = new AtomicTransactionComposer();
656
+ transactionsWithSigner.forEach((txn) => atc.addTransaction(txn));
657
+ return await sendAtomicTransactionComposer({
658
+ atc,
659
+ sendParams
660
+ }, algod);
831
661
  };
832
662
  /**
833
- * Wait until the transaction is confirmed or rejected, or until `timeout`
834
- * number of rounds have passed.
835
- *
836
- * @param algod An algod client
837
- * @param transactionId The transaction ID to wait for
838
- * @param maxRoundsToWait Maximum number of rounds to wait
839
- *
840
- * @return Pending transaction information
841
- * @throws Throws an error if the transaction is not confirmed or rejected in the next `timeout` rounds
842
- */
843
- const waitForConfirmation = async function (transactionId, maxRoundsToWait, algod) {
844
- if (maxRoundsToWait < 0) {
845
- throw new Error(`Invalid timeout, received ${maxRoundsToWait}, expected > 0`);
846
- }
847
- // Get current round
848
- const status = await algod.status().do();
849
- if (status === undefined) {
850
- throw new Error('Unable to get node status');
851
- }
852
- // Loop for up to `timeout` rounds looking for a confirmed transaction
853
- const startRound = BigInt(status.lastRound) + 1n;
854
- let currentRound = startRound;
855
- while (currentRound < startRound + BigInt(maxRoundsToWait)) {
856
- try {
857
- const pendingInfo = await algod.pendingTransactionInformation(transactionId).do();
858
- if (pendingInfo !== undefined) {
859
- const confirmedRound = pendingInfo.confirmedRound;
860
- if (confirmedRound && confirmedRound > 0) {
861
- return pendingInfo;
862
- }
863
- else {
864
- const poolError = pendingInfo.poolError;
865
- if (poolError != null && poolError.length > 0) {
866
- // If there was a pool error, then the transaction has been rejected!
867
- throw new Error(`Transaction ${transactionId} was rejected; pool error: ${poolError}`);
868
- }
869
- }
870
- }
871
- }
872
- catch (e) {
873
- if (e.name === 'URLTokenBaseHTTPError') {
874
- currentRound++;
875
- continue;
876
- }
877
- }
878
- await algod.statusAfterBlock(util.toNumber(currentRound)).do();
879
- currentRound++;
880
- }
881
- throw new Error(`Transaction ${transactionId} not confirmed after ${maxRoundsToWait} rounds`);
663
+ * Wait until the transaction is confirmed or rejected, or until `timeout`
664
+ * number of rounds have passed.
665
+ *
666
+ * @param algod An algod client
667
+ * @param transactionId The transaction ID to wait for
668
+ * @param maxRoundsToWait Maximum number of rounds to wait
669
+ *
670
+ * @return Pending transaction information
671
+ * @throws Throws an error if the transaction is not confirmed or rejected in the next `timeout` rounds
672
+ */
673
+ const waitForConfirmation = async function(transactionId, maxRoundsToWait, algod) {
674
+ if (maxRoundsToWait < 0) throw new Error(`Invalid timeout, received ${maxRoundsToWait}, expected > 0`);
675
+ const status = await algod.status().do();
676
+ if (status === void 0) throw new Error("Unable to get node status");
677
+ const startRound = BigInt(status.lastRound) + 1n;
678
+ let currentRound = startRound;
679
+ while (currentRound < startRound + BigInt(maxRoundsToWait)) {
680
+ try {
681
+ const pendingInfo = await algod.pendingTransactionInformation(transactionId).do();
682
+ if (pendingInfo !== void 0) {
683
+ const confirmedRound = pendingInfo.confirmedRound;
684
+ if (confirmedRound && confirmedRound > 0) return pendingInfo;
685
+ else {
686
+ const poolError = pendingInfo.poolError;
687
+ if (poolError != null && poolError.length > 0) throw new Error(`Transaction ${transactionId} was rejected; pool error: ${poolError}`);
688
+ }
689
+ }
690
+ } catch (e) {
691
+ if (e.name === "URLTokenBaseHTTPError") {
692
+ currentRound++;
693
+ continue;
694
+ }
695
+ }
696
+ await algod.statusAfterBlock(require_util.toNumber(currentRound)).do();
697
+ currentRound++;
698
+ }
699
+ throw new Error(`Transaction ${transactionId} not confirmed after ${maxRoundsToWait} rounds`);
882
700
  };
883
701
  /**
884
- * @deprecated Use `TransactionComposer` and the `maxFee` field in the transaction params instead.
885
- *
886
- * Limit the acceptable fee to a defined amount of µAlgo.
887
- * This also sets the transaction to be flatFee to ensure the transaction only succeeds at
888
- * the estimated rate.
889
- * @param transaction The transaction to cap or suggested params object about to be used to create a transaction
890
- * @param maxAcceptableFee The maximum acceptable fee to pay
891
- */
702
+ * @deprecated Use `TransactionComposer` and the `maxFee` field in the transaction params instead.
703
+ *
704
+ * Limit the acceptable fee to a defined amount of µAlgo.
705
+ * This also sets the transaction to be flatFee to ensure the transaction only succeeds at
706
+ * the estimated rate.
707
+ * @param transaction The transaction to cap or suggested params object about to be used to create a transaction
708
+ * @param maxAcceptableFee The maximum acceptable fee to pay
709
+ */
892
710
  function capTransactionFee(transaction, maxAcceptableFee) {
893
- // If a flat fee hasn't already been defined
894
- if (!('flatFee' in transaction) || !transaction.flatFee) {
895
- // Once a transaction has been constructed by algosdk, transaction.fee indicates what the total transaction fee
896
- // Will be based on the current suggested fee-per-byte value.
897
- if (transaction.fee > maxAcceptableFee.microAlgo) {
898
- 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.`);
899
- }
900
- else if (transaction.fee > 1000000) {
901
- config.Config.logger.warn(`Algorand network congestion fees are in effect. This transaction will incur a fee of ${transaction.fee} µALGO.`);
902
- }
903
- // Now set the flat on the transaction. Otherwise the network may increase the fee above our cap and perform the transaction.
904
- if ('flatFee' in transaction) {
905
- transaction.flatFee = true;
906
- }
907
- }
711
+ if (!("flatFee" in transaction) || !transaction.flatFee) {
712
+ if (transaction.fee > maxAcceptableFee.microAlgo) 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.`);
713
+ else if (transaction.fee > 1e6) require_config.Config.logger.warn(`Algorand network congestion fees are in effect. This transaction will incur a fee of ${transaction.fee} µALGO.`);
714
+ if ("flatFee" in transaction) transaction.flatFee = true;
715
+ }
908
716
  }
909
717
  /**
910
- * @deprecated Use `TransactionComposer` and the `maxFee` and `staticFee` fields in the transaction params instead.
911
- *
912
- * Allows for control of fees on a `Transaction` or `SuggestedParams` object
913
- * @param transaction The transaction or suggested params
914
- * @param feeControl The fee control parameters
915
- */
718
+ * @deprecated Use `TransactionComposer` and the `maxFee` and `staticFee` fields in the transaction params instead.
719
+ *
720
+ * Allows for control of fees on a `Transaction` or `SuggestedParams` object
721
+ * @param transaction The transaction or suggested params
722
+ * @param feeControl The fee control parameters
723
+ */
916
724
  function controlFees(transaction, feeControl) {
917
- const { fee, maxFee } = feeControl;
918
- if (fee) {
919
- transaction.fee = Number(fee.microAlgo);
920
- if ('flatFee' in transaction) {
921
- transaction.flatFee = true;
922
- }
923
- }
924
- if (maxFee !== undefined) {
925
- capTransactionFee(transaction, maxFee);
926
- }
927
- return transaction;
725
+ const { fee, maxFee } = feeControl;
726
+ if (fee) {
727
+ transaction.fee = Number(fee.microAlgo);
728
+ if ("flatFee" in transaction) transaction.flatFee = true;
729
+ }
730
+ if (maxFee !== void 0) capTransactionFee(transaction, maxFee);
731
+ return transaction;
928
732
  }
929
733
  /**
930
- * @deprecated Use `suggestedParams ? { ...suggestedParams } : await algod.getTransactionParams().do()` instead
931
- *
932
- * Returns suggested transaction parameters from algod unless some are already provided.
933
- * @param params Optionally provide parameters to use
934
- * @param algod Algod algod
935
- * @returns The suggested transaction parameters
936
- */
734
+ * @deprecated Use `suggestedParams ? { ...suggestedParams } : await algod.getTransactionParams().do()` instead
735
+ *
736
+ * Returns suggested transaction parameters from algod unless some are already provided.
737
+ * @param params Optionally provide parameters to use
738
+ * @param algod Algod algod
739
+ * @returns The suggested transaction parameters
740
+ */
937
741
  async function getTransactionParams(params, algod) {
938
- if (params) {
939
- return { ...params };
940
- }
941
- const p = await algod.getTransactionParams().do();
942
- return {
943
- fee: p.fee,
944
- firstValid: p.firstValid,
945
- lastValid: p.lastValid,
946
- genesisID: p.genesisID,
947
- genesisHash: p.genesisHash,
948
- minFee: p.minFee,
949
- };
742
+ if (params) return { ...params };
743
+ const p = await algod.getTransactionParams().do();
744
+ return {
745
+ fee: p.fee,
746
+ firstValid: p.firstValid,
747
+ lastValid: p.lastValid,
748
+ genesisID: p.genesisID,
749
+ genesisHash: p.genesisHash,
750
+ minFee: p.minFee
751
+ };
950
752
  }
951
753
  /**
952
- * @deprecated Use `atc.clone().buildGroup()` instead.
953
- *
954
- * Returns the array of transactions currently present in the given `AtomicTransactionComposer`
955
- * @param atc The atomic transaction composer
956
- * @returns The array of transactions with signers
957
- */
754
+ * @deprecated Use `atc.clone().buildGroup()` instead.
755
+ *
756
+ * Returns the array of transactions currently present in the given `AtomicTransactionComposer`
757
+ * @param atc The atomic transaction composer
758
+ * @returns The array of transactions with signers
759
+ */
958
760
  function getAtomicTransactionComposerTransactions(atc) {
959
- try {
960
- return atc.clone().buildGroup();
961
- }
962
- catch {
963
- return [];
964
- }
761
+ try {
762
+ return atc.clone().buildGroup();
763
+ } catch {
764
+ return [];
765
+ }
965
766
  }
966
-
767
+ //#endregion
967
768
  exports.MAX_APP_CALL_ACCOUNT_REFERENCES = MAX_APP_CALL_ACCOUNT_REFERENCES;
968
769
  exports.MAX_APP_CALL_FOREIGN_REFERENCES = MAX_APP_CALL_FOREIGN_REFERENCES;
969
770
  exports.MAX_TRANSACTION_GROUP_SIZE = MAX_TRANSACTION_GROUP_SIZE;
@@ -984,4 +785,5 @@ exports.sendGroupOfTransactions = sendGroupOfTransactions;
984
785
  exports.sendTransaction = sendTransaction;
985
786
  exports.signTransaction = signTransaction;
986
787
  exports.waitForConfirmation = waitForConfirmation;
987
- //# sourceMappingURL=transaction.js.map
788
+
789
+ //# sourceMappingURL=transaction.js.map