@algorandfoundation/algokit-utils 7.0.0-beta.8 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/account/account.js +6 -4
  4. package/account/account.js.map +1 -1
  5. package/account/account.mjs +6 -4
  6. package/account/account.mjs.map +1 -1
  7. package/account/get-account-config-from-environment.js.map +1 -1
  8. package/account/get-account-config-from-environment.mjs.map +1 -1
  9. package/account/get-account.js.map +1 -1
  10. package/account/get-account.mjs.map +1 -1
  11. package/account/get-dispenser-account.js.map +1 -1
  12. package/account/get-dispenser-account.mjs.map +1 -1
  13. package/account/mnemonic-account.js.map +1 -1
  14. package/account/mnemonic-account.mjs.map +1 -1
  15. package/amount.js.map +1 -1
  16. package/amount.mjs.map +1 -1
  17. package/app-client.js.map +1 -1
  18. package/app-client.mjs.map +1 -1
  19. package/app-deploy.js +2 -10
  20. package/app-deploy.js.map +1 -1
  21. package/app-deploy.mjs +3 -11
  22. package/app-deploy.mjs.map +1 -1
  23. package/app.d.ts +2 -2
  24. package/app.js +2 -2
  25. package/app.js.map +1 -1
  26. package/app.mjs +2 -2
  27. package/app.mjs.map +1 -1
  28. package/asset.js.map +1 -1
  29. package/asset.mjs.map +1 -1
  30. package/debugging/debugging.js.map +1 -1
  31. package/debugging/debugging.mjs.map +1 -1
  32. package/dispenser-client.js.map +1 -1
  33. package/dispenser-client.mjs.map +1 -1
  34. package/index.d.ts +1 -0
  35. package/index.js +6 -0
  36. package/index.js.map +1 -1
  37. package/index.mjs +2 -1
  38. package/index.mjs.map +1 -1
  39. package/indexer-lookup.js.map +1 -1
  40. package/indexer-lookup.mjs.map +1 -1
  41. package/localnet/get-kmd-wallet-account.js.map +1 -1
  42. package/localnet/get-kmd-wallet-account.mjs.map +1 -1
  43. package/localnet/get-localnet-dispenser-account.js.map +1 -1
  44. package/localnet/get-localnet-dispenser-account.mjs.map +1 -1
  45. package/localnet/get-or-create-kmd-wallet-account.js.map +1 -1
  46. package/localnet/get-or-create-kmd-wallet-account.mjs.map +1 -1
  47. package/localnet/is-localnet.js.map +1 -1
  48. package/localnet/is-localnet.mjs.map +1 -1
  49. package/network-client.js.map +1 -1
  50. package/network-client.mjs.map +1 -1
  51. package/package.json +5 -5
  52. package/testing/account.js.map +1 -1
  53. package/testing/account.mjs.map +1 -1
  54. package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
  55. package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
  56. package/testing/fixtures/algorand-fixture.js.map +1 -1
  57. package/testing/fixtures/algorand-fixture.mjs.map +1 -1
  58. package/testing/indexer.js.map +1 -1
  59. package/testing/indexer.mjs.map +1 -1
  60. package/testing/test-logger.js.map +1 -1
  61. package/testing/test-logger.mjs.map +1 -1
  62. package/testing/transaction-logger.js.map +1 -1
  63. package/testing/transaction-logger.mjs.map +1 -1
  64. package/transaction/legacy-bridge.js +2 -2
  65. package/transaction/legacy-bridge.js.map +1 -1
  66. package/transaction/legacy-bridge.mjs +3 -3
  67. package/transaction/legacy-bridge.mjs.map +1 -1
  68. package/transaction/perform-atomic-transaction-composer-simulate.js +1 -0
  69. package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
  70. package/transaction/perform-atomic-transaction-composer-simulate.mjs +1 -0
  71. package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
  72. package/transaction/transaction.d.ts +14 -7
  73. package/transaction/transaction.js +57 -31
  74. package/transaction/transaction.js.map +1 -1
  75. package/transaction/transaction.mjs +55 -30
  76. package/transaction/transaction.mjs.map +1 -1
  77. package/transfer/transfer-algos.js.map +1 -1
  78. package/transfer/transfer-algos.mjs.map +1 -1
  79. package/transfer/transfer.js.map +1 -1
  80. package/transfer/transfer.mjs.map +1 -1
  81. package/types/account-manager.d.ts +1 -1
  82. package/types/account-manager.js +10 -8
  83. package/types/account-manager.js.map +1 -1
  84. package/types/account-manager.mjs +11 -9
  85. package/types/account-manager.mjs.map +1 -1
  86. package/types/account.d.ts +9 -0
  87. package/types/account.js.map +1 -1
  88. package/types/account.mjs.map +1 -1
  89. package/types/algo-http-client-with-retry.js.map +1 -1
  90. package/types/algo-http-client-with-retry.mjs.map +1 -1
  91. package/types/algorand-client-interface.d.ts +2 -2
  92. package/types/algorand-client-transaction-creator.d.ts +5 -3
  93. package/types/algorand-client-transaction-creator.js +3 -1
  94. package/types/algorand-client-transaction-creator.js.map +1 -1
  95. package/types/algorand-client-transaction-creator.mjs +3 -1
  96. package/types/algorand-client-transaction-creator.mjs.map +1 -1
  97. package/types/algorand-client-transaction-sender.d.ts +12 -8
  98. package/types/algorand-client-transaction-sender.js +6 -2
  99. package/types/algorand-client-transaction-sender.js.map +1 -1
  100. package/types/algorand-client-transaction-sender.mjs +6 -2
  101. package/types/algorand-client-transaction-sender.mjs.map +1 -1
  102. package/types/algorand-client.d.ts +3 -4
  103. package/types/algorand-client.js +2 -5
  104. package/types/algorand-client.js.map +1 -1
  105. package/types/algorand-client.mjs +4 -4
  106. package/types/algorand-client.mjs.map +1 -1
  107. package/types/amount.js.map +1 -1
  108. package/types/amount.mjs.map +1 -1
  109. package/types/app-arc56.d.ts +31 -20
  110. package/types/app-arc56.js.map +1 -1
  111. package/types/app-arc56.mjs.map +1 -1
  112. package/types/app-client.d.ts +97 -78
  113. package/types/app-client.js +171 -54
  114. package/types/app-client.js.map +1 -1
  115. package/types/app-client.mjs +169 -52
  116. package/types/app-client.mjs.map +1 -1
  117. package/types/app-deployer.js +1 -1
  118. package/types/app-deployer.js.map +1 -1
  119. package/types/app-deployer.mjs +2 -2
  120. package/types/app-deployer.mjs.map +1 -1
  121. package/types/app-factory.d.ts +30 -10
  122. package/types/app-factory.js +26 -20
  123. package/types/app-factory.js.map +1 -1
  124. package/types/app-factory.mjs +26 -20
  125. package/types/app-factory.mjs.map +1 -1
  126. package/types/app-manager.js +105 -23
  127. package/types/app-manager.js.map +1 -1
  128. package/types/app-manager.mjs +105 -23
  129. package/types/app-manager.mjs.map +1 -1
  130. package/types/app-spec.js +8 -2
  131. package/types/app-spec.js.map +1 -1
  132. package/types/app-spec.mjs +8 -2
  133. package/types/app-spec.mjs.map +1 -1
  134. package/types/app.d.ts +8 -7
  135. package/types/app.js.map +1 -1
  136. package/types/app.mjs.map +1 -1
  137. package/types/asset-manager.d.ts +4 -4
  138. package/types/asset-manager.js +2 -2
  139. package/types/asset-manager.js.map +1 -1
  140. package/types/asset-manager.mjs +2 -2
  141. package/types/asset-manager.mjs.map +1 -1
  142. package/types/async-event-emitter.d.ts +1 -10
  143. package/types/async-event-emitter.js +0 -5
  144. package/types/async-event-emitter.js.map +1 -1
  145. package/types/async-event-emitter.mjs +1 -6
  146. package/types/async-event-emitter.mjs.map +1 -1
  147. package/types/client-manager.js +2 -2
  148. package/types/client-manager.js.map +1 -1
  149. package/types/client-manager.mjs +2 -2
  150. package/types/client-manager.mjs.map +1 -1
  151. package/types/composer.d.ts +40 -25
  152. package/types/composer.js +114 -40
  153. package/types/composer.js.map +1 -1
  154. package/types/composer.mjs +115 -39
  155. package/types/composer.mjs.map +1 -1
  156. package/types/config.js.map +1 -1
  157. package/types/config.mjs.map +1 -1
  158. package/types/debugging.d.ts +1 -1
  159. package/types/debugging.js +1 -1
  160. package/types/debugging.js.map +1 -1
  161. package/types/debugging.mjs +1 -1
  162. package/types/debugging.mjs.map +1 -1
  163. package/types/dispenser-client.js.map +1 -1
  164. package/types/dispenser-client.mjs.map +1 -1
  165. package/types/indexer.js.map +1 -1
  166. package/types/indexer.mjs.map +1 -1
  167. package/types/kmd-account-manager.js +1 -1
  168. package/types/kmd-account-manager.js.map +1 -1
  169. package/types/kmd-account-manager.mjs +2 -2
  170. package/types/kmd-account-manager.mjs.map +1 -1
  171. package/types/lifecycle-events.d.ts +10 -0
  172. package/types/lifecycle-events.js +8 -0
  173. package/types/lifecycle-events.js.map +1 -0
  174. package/types/lifecycle-events.mjs +8 -0
  175. package/types/lifecycle-events.mjs.map +1 -0
  176. package/types/logging.js.map +1 -1
  177. package/types/logging.mjs.map +1 -1
  178. package/types/logic-error.d.ts +2 -3
  179. package/types/logic-error.js +3 -3
  180. package/types/logic-error.js.map +1 -1
  181. package/types/logic-error.mjs +3 -3
  182. package/types/logic-error.mjs.map +1 -1
  183. package/types/network-client.js.map +1 -1
  184. package/types/network-client.mjs.map +1 -1
  185. package/types/testing.d.ts +1 -1
  186. package/types/urlTokenBaseHTTPClient.js.map +1 -1
  187. package/types/urlTokenBaseHTTPClient.mjs.map +1 -1
  188. package/util.js.map +1 -1
  189. package/util.mjs.map +1 -1
@@ -9,7 +9,7 @@ import { binaryStartsWith } from '../util.mjs';
9
9
  import { UPDATABLE_TEMPLATE_NAME, DELETABLE_TEMPLATE_NAME } from './app.mjs';
10
10
  import { getArc56Method, getArc56ReturnValue, getABITupleFromABIStruct, getABIDecodedValue, getABIEncodedValue } from './app-arc56.mjs';
11
11
  import { arc32ToArc56 } from './app-spec.mjs';
12
- import { EventType } from './async-event-emitter.mjs';
12
+ import { EventType } from './lifecycle-events.mjs';
13
13
  import { LogicError } from './logic-error.mjs';
14
14
 
15
15
  var ABIMethod = algosdk.ABIMethod;
@@ -40,6 +40,57 @@ function getDeployTimeControl(approval, appSpec, templateVariableName, callConfi
40
40
  return !!abiCallConfig && abiCallConfig !== 'NEVER';
41
41
  });
42
42
  }
43
+ const BYTE_CBLOCK = 38;
44
+ const INT_CBLOCK = 32;
45
+ /**
46
+ * Get the offset of the last constant block at the beginning of the program
47
+ * This value is used to calculate the program counter for an ARC56 program that has a pcOffsetMethod of "cblocks"
48
+ *
49
+ * @param program The program to parse
50
+ * @returns The PC value of the opcode after the last constant block
51
+ */
52
+ function getConstantBlockOffset(program) {
53
+ const bytes = [...program];
54
+ const programSize = bytes.length;
55
+ bytes.shift(); // remove version
56
+ /** The PC of the opcode after the bytecblock */
57
+ let bytecblockOffset;
58
+ /** The PC of the opcode after the intcblock */
59
+ let intcblockOffset;
60
+ while (bytes.length > 0) {
61
+ /** The current byte from the beginning of the byte array */
62
+ const byte = bytes.shift();
63
+ // If the byte is a constant block...
64
+ if (byte === BYTE_CBLOCK || byte === INT_CBLOCK) {
65
+ const isBytecblock = byte === BYTE_CBLOCK;
66
+ /** The byte following the opcode is the number of values in the constant block */
67
+ const valuesRemaining = bytes.shift();
68
+ // Iterate over all the values in the constant block
69
+ for (let i = 0; i < valuesRemaining; i++) {
70
+ if (isBytecblock) {
71
+ /** The byte following the opcode is the length of the next element */
72
+ const length = bytes.shift();
73
+ bytes.splice(0, length);
74
+ }
75
+ else {
76
+ // intcblock is a uvarint, so we need to keep reading until we find the end (MSB is not set)
77
+ while ((bytes.shift() & 0x80) !== 0) {
78
+ // Do nothing...
79
+ }
80
+ }
81
+ }
82
+ if (isBytecblock)
83
+ bytecblockOffset = programSize - bytes.length - 1;
84
+ else
85
+ intcblockOffset = programSize - bytes.length - 1;
86
+ if (bytes[0] !== BYTE_CBLOCK && bytes[0] !== INT_CBLOCK) {
87
+ // if the next opcode isn't a constant block, we're done
88
+ break;
89
+ }
90
+ }
91
+ }
92
+ return Math.max(bytecblockOffset ?? 0, intcblockOffset ?? 0);
93
+ }
43
94
  /** ARC-56/ARC-32 application client that allows you to manage calls and
44
95
  * state for a specific deployed instance of an app (with a known app ID). */
45
96
  class AppClient {
@@ -50,6 +101,7 @@ class AppClient {
50
101
  this._appName = params.appName ?? this._appSpec.name;
51
102
  this._algorand = params.algorand;
52
103
  this._defaultSender = params.defaultSender;
104
+ this._defaultSigner = params.defaultSigner;
53
105
  this._approvalSourceMap = params.approvalSourceMap;
54
106
  this._clearSourceMap = params.clearSourceMap;
55
107
  this._localStateMethods = (address) => this.getStateMethods(() => this.getLocalState(address), () => this._appSpec.state.keys.local, () => this._appSpec.state.maps.local);
@@ -71,9 +123,24 @@ class AppClient {
71
123
  bare: this.getBareSendMethods(),
72
124
  };
73
125
  }
74
- /** Start a new `AlgoKitComposer` transaction group */
75
- newGroup() {
76
- return this._algorand.newGroup();
126
+ /**
127
+ * Clone this app client with different params
128
+ *
129
+ * @param params The params to use for the the cloned app client. Omit a param to keep the original value. Set a param to override the original value. Setting to undefined will clear the original value.
130
+ * @returns A new app client with the altered params
131
+ */
132
+ clone(params) {
133
+ return new AppClient({
134
+ appId: this._appId,
135
+ appSpec: this._appSpec,
136
+ algorand: this._algorand,
137
+ appName: this._appName,
138
+ defaultSender: this._defaultSender,
139
+ defaultSigner: this._defaultSigner,
140
+ approvalSourceMap: this._approvalSourceMap,
141
+ clearSourceMap: this._clearSourceMap,
142
+ ...params,
143
+ });
77
144
  }
78
145
  /**
79
146
  * Returns a new `AppClient` client, resolving the app by creator address and name
@@ -145,6 +212,10 @@ class AppClient {
145
212
  get appSpec() {
146
213
  return this._appSpec;
147
214
  }
215
+ /** A reference to the underlying `AlgorandClient` this app client is using. */
216
+ get algorand() {
217
+ return this._algorand;
218
+ }
148
219
  /** Get parameters to create transactions for the current app.
149
220
  *
150
221
  * A good mental model for this is that these parameters represent a deferred transaction creation.
@@ -276,11 +347,19 @@ class AppClient {
276
347
  * @param isClearStateProgram Whether or not the code was running the clear state program (defaults to approval program)
277
348
  * @returns The new error, or if there was no logic error or source map then the wrapped error with source details
278
349
  */
279
- exposeLogicError(e, isClearStateProgram) {
350
+ async exposeLogicError(e, isClearStateProgram) {
351
+ const pcOffsetMethod = this._appSpec.sourceInfo?.[isClearStateProgram ? 'clear' : 'approval']?.pcOffsetMethod;
352
+ let program;
353
+ if (pcOffsetMethod === 'cblocks') {
354
+ // TODO: Cache this if we deploy the app and it's not updateable
355
+ const appInfo = await this._algorand.app.getById(this.appId);
356
+ program = isClearStateProgram ? appInfo.clearStateProgram : appInfo.approvalProgram;
357
+ }
280
358
  return AppClient.exposeLogicError(e, this._appSpec, {
281
359
  isClearStateProgram,
282
360
  approvalSourceMap: this._approvalSourceMap,
283
361
  clearSourceMap: this._clearSourceMap,
362
+ program,
284
363
  });
285
364
  }
286
365
  /**
@@ -338,11 +417,11 @@ class AppClient {
338
417
  */
339
418
  async compile(compilation) {
340
419
  const result = await AppClient.compile(this._appSpec, this._algorand.app, compilation);
341
- if (result.approvalProgramCompilationResult) {
342
- this._approvalSourceMap = result.approvalProgramCompilationResult.sourceMap;
420
+ if (result.compiledApproval) {
421
+ this._approvalSourceMap = result.compiledApproval.sourceMap;
343
422
  }
344
- if (result.clearStateProgramCompilationResult) {
345
- this._clearSourceMap = result.clearStateProgramCompilationResult.sourceMap;
423
+ if (result.compiledClear) {
424
+ this._clearSourceMap = result.compiledClear.sourceMap;
346
425
  }
347
426
  return result;
348
427
  }
@@ -355,17 +434,45 @@ class AppClient {
355
434
  * @returns The new error, or if there was no logic error or source map then the wrapped error with source details
356
435
  */
357
436
  static exposeLogicError(e, appSpec, details) {
358
- const { isClearStateProgram, approvalSourceMap, clearSourceMap } = details;
359
- if ((!isClearStateProgram && approvalSourceMap == undefined) || (isClearStateProgram && clearSourceMap == undefined))
360
- return e;
437
+ const { isClearStateProgram, approvalSourceMap, clearSourceMap, program } = details;
438
+ const sourceMap = isClearStateProgram ? clearSourceMap : approvalSourceMap;
361
439
  const errorDetails = LogicError.parseLogicError(e);
362
- const errorMessage = (isClearStateProgram ? appSpec.sourceInfo?.clear : appSpec.sourceInfo?.approval)?.find((s) => s?.pc?.includes(errorDetails?.pc ?? -1))?.errorMessage;
363
- if (errorDetails !== undefined && appSpec.source)
440
+ // Return the error if we don't have a PC
441
+ if (errorDetails === undefined || errorDetails?.pc === undefined)
442
+ return e;
443
+ /** The PC value to find in the ARC56 SourceInfo */
444
+ let arc56Pc = errorDetails?.pc;
445
+ const programSourceInfo = isClearStateProgram ? appSpec.sourceInfo?.clear : appSpec.sourceInfo?.approval;
446
+ /** The offset to apply to the PC if using the cblocks pc offset method */
447
+ let cblocksOffset = 0;
448
+ // If the program uses cblocks offset, then we need to adjust the PC accordingly
449
+ if (programSourceInfo?.pcOffsetMethod === 'cblocks') {
450
+ if (program === undefined)
451
+ throw new Error('Program bytes are required to calculate the ARC56 cblocks PC offset');
452
+ cblocksOffset = getConstantBlockOffset(program);
453
+ arc56Pc = errorDetails.pc - cblocksOffset;
454
+ }
455
+ // Find the source info for this PC and get the error message
456
+ const sourceInfo = programSourceInfo?.sourceInfo.find((s) => s.pc.includes(arc56Pc));
457
+ const errorMessage = sourceInfo?.errorMessage;
458
+ // If we have the source we can display the TEAL in the error message
459
+ if (appSpec.source) {
460
+ let getLineForPc = (inputPc) => sourceMap?.getLineForPc?.(inputPc);
461
+ // If the SourceMap is not defined, we need to provide our own function for going from a PC to TEAL based on ARC56 SourceInfo[]
462
+ if (sourceMap === undefined) {
463
+ getLineForPc = (inputPc) => {
464
+ const teal = programSourceInfo?.sourceInfo.find((s) => s.pc.includes(inputPc - cblocksOffset))?.teal;
465
+ if (teal === undefined)
466
+ return undefined;
467
+ return teal - 1;
468
+ };
469
+ }
364
470
  e = new LogicError(errorDetails, Buffer.from(isClearStateProgram ? appSpec.source.clear : appSpec.source.approval, 'base64')
365
471
  .toString()
366
472
  .split('\n'),
367
473
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
368
- isClearStateProgram ? clearSourceMap : approvalSourceMap);
474
+ getLineForPc);
475
+ }
369
476
  if (errorMessage) {
370
477
  const appId = JSON.stringify(e).match(/(?<=app=)\d+/)?.[0] || '';
371
478
  const txId = JSON.stringify(e).match(/(?<=transaction )\S+(?=:)/)?.[0];
@@ -398,25 +505,25 @@ class AppClient {
398
505
  };
399
506
  }
400
507
  const approvalTemplate = Buffer.from(appSpec.source.approval, 'base64').toString('utf-8');
401
- const approvalProgramCompilationResult = await appManager.compileTealTemplate(approvalTemplate, deployTimeParams, {
508
+ const compiledApproval = await appManager.compileTealTemplate(approvalTemplate, deployTimeParams, {
402
509
  updatable,
403
510
  deletable,
404
511
  });
405
512
  const clearTemplate = Buffer.from(appSpec.source.clear, 'base64').toString('utf-8');
406
- const clearStateProgramCompilationResult = await appManager.compileTealTemplate(clearTemplate, deployTimeParams);
513
+ const compiledClear = await appManager.compileTealTemplate(clearTemplate, deployTimeParams);
407
514
  if (Config.debug) {
408
515
  await Config.events.emitAsync(EventType.AppCompiled, {
409
516
  sources: [
410
- { compiledTeal: approvalProgramCompilationResult, appName: appSpec.name, fileName: 'approval' },
411
- { compiledTeal: clearStateProgramCompilationResult, appName: appSpec.name, fileName: 'clear' },
517
+ { compiledTeal: compiledApproval, appName: appSpec.name, fileName: 'approval' },
518
+ { compiledTeal: compiledClear, appName: appSpec.name, fileName: 'clear' },
412
519
  ],
413
520
  });
414
521
  }
415
522
  return {
416
- approvalProgram: approvalProgramCompilationResult.compiledBase64ToBytes,
417
- approvalProgramCompilationResult,
418
- clearStateProgram: clearStateProgramCompilationResult.compiledBase64ToBytes,
419
- clearStateProgramCompilationResult,
523
+ approvalProgram: compiledApproval.compiledBase64ToBytes,
524
+ compiledApproval,
525
+ clearStateProgram: compiledClear.compiledBase64ToBytes,
526
+ compiledClear,
420
527
  };
421
528
  }
422
529
  /**
@@ -442,19 +549,22 @@ class AppClient {
442
549
  if (defaultValue) {
443
550
  switch (defaultValue.source) {
444
551
  case 'literal':
445
- if (typeof defaultValue.data === 'number')
446
- return defaultValue.data;
447
552
  return getABIDecodedValue(Buffer.from(defaultValue.data, 'base64'), m.method.args[i].defaultValue?.type ?? m.method.args[i].type, this._appSpec.structs);
448
- // todo: When ARC-56 supports ABI calls as default args
449
- // case 'abi': {
450
- // const method = this.getABIMethod(defaultValue.data as string)
451
- // const result = await this.send.call({
452
- // method: defaultValue.data as string,
453
- // methodArgs: method.args.map(() => undefined),
454
- // sender,
455
- // })
456
- // return result.return!
457
- // }
553
+ case 'method': {
554
+ const method = this.getABIMethod(defaultValue.data);
555
+ const result = await this.send.call({
556
+ method: defaultValue.data,
557
+ args: method.args.map(() => undefined),
558
+ sender,
559
+ });
560
+ if (result.return === undefined) {
561
+ throw new Error('Default value method call did not return a value');
562
+ }
563
+ if (typeof result.return === 'object' && !(result.return instanceof Uint8Array) && !Array.isArray(result.return)) {
564
+ return getABITupleFromABIStruct(result.return, this._appSpec.structs[method.returns.struct], this._appSpec.structs);
565
+ }
566
+ return result.return;
567
+ }
458
568
  case 'local':
459
569
  case 'global': {
460
570
  const state = defaultValue.source === 'global' ? await this.getGlobalState() : await this.getLocalState(sender);
@@ -472,7 +582,9 @@ class AppClient {
472
582
  }
473
583
  }
474
584
  }
475
- throw new Error(`No value provided for required argument ${arg.name ?? `arg${i + 1}`} in call to method ${m.name}`);
585
+ if (!algosdk.abiTypeIsTransaction(arg.type)) {
586
+ throw new Error(`No value provided for required argument ${arg.name ?? `arg${i + 1}`} in call to method ${m.name}`);
587
+ }
476
588
  }) ?? []);
477
589
  }
478
590
  getBareParamsMethods() {
@@ -541,10 +653,7 @@ class AppClient {
541
653
  const compiled = await this.compile(params);
542
654
  return {
543
655
  ...(await this.handleCallErrors(async () => this._algorand.send.appUpdate(await this.params.bare.update(params)))),
544
- ...{
545
- compiledApproval: compiled.approvalProgramCompilationResult,
546
- compiledClear: compiled.clearStateProgramCompilationResult,
547
- },
656
+ ...compiled,
548
657
  };
549
658
  },
550
659
  /** Signs and sends an opt-in call */
@@ -576,6 +685,7 @@ class AppClient {
576
685
  return {
577
686
  ...params,
578
687
  sender: this.getSender(params.sender),
688
+ signer: this.getSigner(params.sender, params.signer),
579
689
  receiver: this.appAddress,
580
690
  };
581
691
  },
@@ -617,10 +727,7 @@ class AppClient {
617
727
  const compiled = await this.compile(params);
618
728
  return {
619
729
  ...(await this.handleCallErrors(async () => this.processMethodCallReturn(this._algorand.send.appUpdateMethodCall(await this.params.update({ ...params })), getArc56Method(params.method, this._appSpec)))),
620
- ...{
621
- compiledApproval: compiled.approvalProgramCompilationResult,
622
- compiledClear: compiled.clearStateProgramCompilationResult,
623
- },
730
+ ...compiled,
624
731
  };
625
732
  },
626
733
  /**
@@ -646,13 +753,15 @@ class AppClient {
646
753
  */
647
754
  call: async (params) => {
648
755
  // Read-only call - do it via simulate
649
- if (params.onComplete === OnApplicationComplete.NoOpOC ||
650
- (!params.onComplete && getArc56Method(params.method, this._appSpec).method.readonly)) {
756
+ if ((params.onComplete === OnApplicationComplete.NoOpOC || !params.onComplete) &&
757
+ getArc56Method(params.method, this._appSpec).method.readonly) {
651
758
  const result = await this._algorand
652
759
  .newGroup()
653
760
  .addAppCallMethodCall(await this.params.call(params))
654
761
  .simulate({
655
- allowUnnamedResources: params.populateAppCallResources,
762
+ allowUnnamedResources: params.populateAppCallResources ?? true,
763
+ // Simulate calls for a readonly method shouldn't invoke signing
764
+ skipSignatures: true,
656
765
  });
657
766
  return this.processMethodCallReturn({
658
767
  ...result,
@@ -704,7 +813,7 @@ class AppClient {
704
813
  },
705
814
  };
706
815
  }
707
- /** Returns the sender for a call, using the `defaultSender`
816
+ /** Returns the sender for a call, using the provided sender or using the `defaultSender`
708
817
  * if none provided and throws an error if neither provided */
709
818
  getSender(sender) {
710
819
  if (!sender && !this._defaultSender) {
@@ -712,11 +821,18 @@ class AppClient {
712
821
  }
713
822
  return sender ?? this._defaultSender;
714
823
  }
824
+ /** Returns the signer for a call, using the provided signer or the `defaultSigner`
825
+ * if no signer was provided and the call will use default sender
826
+ * or `undefined` otherwise (so the signer is resolved from `AlgorandClient`) */
827
+ getSigner(sender, signer) {
828
+ return signer ?? (!sender ? this._defaultSigner : undefined);
829
+ }
715
830
  getBareParams(params, onComplete) {
716
831
  return {
717
832
  ...params,
718
833
  appId: this._appId,
719
834
  sender: this.getSender(params?.sender),
835
+ signer: this.getSigner(params?.sender, params?.signer),
720
836
  onComplete,
721
837
  };
722
838
  }
@@ -728,6 +844,7 @@ class AppClient {
728
844
  ...params,
729
845
  appId: this._appId,
730
846
  sender: sender,
847
+ signer: this.getSigner(params.sender, params.signer),
731
848
  method,
732
849
  onComplete,
733
850
  args,
@@ -739,7 +856,7 @@ class AppClient {
739
856
  return await call();
740
857
  }
741
858
  catch (e) {
742
- throw this.exposeLogicError(e);
859
+ throw await this.exposeLogicError(e);
743
860
  }
744
861
  }
745
862
  getBoxMethods() {
@@ -1103,7 +1220,7 @@ class ApplicationClient {
1103
1220
  return { ...result, ...{ compiledApproval: approvalCompiled, compiledClear: clearCompiled } };
1104
1221
  }
1105
1222
  catch (e) {
1106
- throw this.exposeLogicError(e);
1223
+ throw await this.exposeLogicError(e);
1107
1224
  }
1108
1225
  }
1109
1226
  /**
@@ -1137,7 +1254,7 @@ class ApplicationClient {
1137
1254
  return { ...result, ...{ compiledApproval: approvalCompiled, compiledClear: clearCompiled } };
1138
1255
  }
1139
1256
  catch (e) {
1140
- throw this.exposeLogicError(e);
1257
+ throw await this.exposeLogicError(e);
1141
1258
  }
1142
1259
  }
1143
1260
  /**
@@ -1490,7 +1607,7 @@ class ApplicationClient {
1490
1607
  .toString()
1491
1608
  .split('\n'),
1492
1609
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1493
- isClear ? this._clearSourceMap : this._approvalSourceMap);
1610
+ (pc) => (isClear ? this._clearSourceMap : this._approvalSourceMap).getLineForPc(pc));
1494
1611
  else
1495
1612
  return e;
1496
1613
  }