@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.
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/account/account.js +6 -4
- package/account/account.js.map +1 -1
- package/account/account.mjs +6 -4
- package/account/account.mjs.map +1 -1
- package/account/get-account-config-from-environment.js.map +1 -1
- package/account/get-account-config-from-environment.mjs.map +1 -1
- package/account/get-account.js.map +1 -1
- package/account/get-account.mjs.map +1 -1
- package/account/get-dispenser-account.js.map +1 -1
- package/account/get-dispenser-account.mjs.map +1 -1
- package/account/mnemonic-account.js.map +1 -1
- package/account/mnemonic-account.mjs.map +1 -1
- package/amount.js.map +1 -1
- package/amount.mjs.map +1 -1
- package/app-client.js.map +1 -1
- package/app-client.mjs.map +1 -1
- package/app-deploy.js +2 -10
- package/app-deploy.js.map +1 -1
- package/app-deploy.mjs +3 -11
- package/app-deploy.mjs.map +1 -1
- package/app.d.ts +2 -2
- package/app.js +2 -2
- package/app.js.map +1 -1
- package/app.mjs +2 -2
- package/app.mjs.map +1 -1
- package/asset.js.map +1 -1
- package/asset.mjs.map +1 -1
- package/debugging/debugging.js.map +1 -1
- package/debugging/debugging.mjs.map +1 -1
- package/dispenser-client.js.map +1 -1
- package/dispenser-client.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +6 -0
- package/index.js.map +1 -1
- package/index.mjs +2 -1
- package/index.mjs.map +1 -1
- package/indexer-lookup.js.map +1 -1
- package/indexer-lookup.mjs.map +1 -1
- package/localnet/get-kmd-wallet-account.js.map +1 -1
- package/localnet/get-kmd-wallet-account.mjs.map +1 -1
- package/localnet/get-localnet-dispenser-account.js.map +1 -1
- package/localnet/get-localnet-dispenser-account.mjs.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.js.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.mjs.map +1 -1
- package/localnet/is-localnet.js.map +1 -1
- package/localnet/is-localnet.mjs.map +1 -1
- package/network-client.js.map +1 -1
- package/network-client.mjs.map +1 -1
- package/package.json +5 -5
- package/testing/account.js.map +1 -1
- package/testing/account.mjs.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
- package/testing/fixtures/algorand-fixture.js.map +1 -1
- package/testing/fixtures/algorand-fixture.mjs.map +1 -1
- package/testing/indexer.js.map +1 -1
- package/testing/indexer.mjs.map +1 -1
- package/testing/test-logger.js.map +1 -1
- package/testing/test-logger.mjs.map +1 -1
- package/testing/transaction-logger.js.map +1 -1
- package/testing/transaction-logger.mjs.map +1 -1
- package/transaction/legacy-bridge.js +2 -2
- package/transaction/legacy-bridge.js.map +1 -1
- package/transaction/legacy-bridge.mjs +3 -3
- package/transaction/legacy-bridge.mjs.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.js +1 -0
- package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.mjs +1 -0
- package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
- package/transaction/transaction.d.ts +14 -7
- package/transaction/transaction.js +57 -31
- package/transaction/transaction.js.map +1 -1
- package/transaction/transaction.mjs +55 -30
- package/transaction/transaction.mjs.map +1 -1
- package/transfer/transfer-algos.js.map +1 -1
- package/transfer/transfer-algos.mjs.map +1 -1
- package/transfer/transfer.js.map +1 -1
- package/transfer/transfer.mjs.map +1 -1
- package/types/account-manager.d.ts +1 -1
- package/types/account-manager.js +10 -8
- package/types/account-manager.js.map +1 -1
- package/types/account-manager.mjs +11 -9
- package/types/account-manager.mjs.map +1 -1
- package/types/account.d.ts +9 -0
- package/types/account.js.map +1 -1
- package/types/account.mjs.map +1 -1
- package/types/algo-http-client-with-retry.js.map +1 -1
- package/types/algo-http-client-with-retry.mjs.map +1 -1
- package/types/algorand-client-interface.d.ts +2 -2
- package/types/algorand-client-transaction-creator.d.ts +5 -3
- package/types/algorand-client-transaction-creator.js +3 -1
- package/types/algorand-client-transaction-creator.js.map +1 -1
- package/types/algorand-client-transaction-creator.mjs +3 -1
- package/types/algorand-client-transaction-creator.mjs.map +1 -1
- package/types/algorand-client-transaction-sender.d.ts +12 -8
- package/types/algorand-client-transaction-sender.js +6 -2
- package/types/algorand-client-transaction-sender.js.map +1 -1
- package/types/algorand-client-transaction-sender.mjs +6 -2
- package/types/algorand-client-transaction-sender.mjs.map +1 -1
- package/types/algorand-client.d.ts +3 -4
- package/types/algorand-client.js +2 -5
- package/types/algorand-client.js.map +1 -1
- package/types/algorand-client.mjs +4 -4
- package/types/algorand-client.mjs.map +1 -1
- package/types/amount.js.map +1 -1
- package/types/amount.mjs.map +1 -1
- package/types/app-arc56.d.ts +31 -20
- package/types/app-arc56.js.map +1 -1
- package/types/app-arc56.mjs.map +1 -1
- package/types/app-client.d.ts +97 -78
- package/types/app-client.js +171 -54
- package/types/app-client.js.map +1 -1
- package/types/app-client.mjs +169 -52
- package/types/app-client.mjs.map +1 -1
- package/types/app-deployer.js +1 -1
- package/types/app-deployer.js.map +1 -1
- package/types/app-deployer.mjs +2 -2
- package/types/app-deployer.mjs.map +1 -1
- package/types/app-factory.d.ts +30 -10
- package/types/app-factory.js +26 -20
- package/types/app-factory.js.map +1 -1
- package/types/app-factory.mjs +26 -20
- package/types/app-factory.mjs.map +1 -1
- package/types/app-manager.js +105 -23
- package/types/app-manager.js.map +1 -1
- package/types/app-manager.mjs +105 -23
- package/types/app-manager.mjs.map +1 -1
- package/types/app-spec.js +8 -2
- package/types/app-spec.js.map +1 -1
- package/types/app-spec.mjs +8 -2
- package/types/app-spec.mjs.map +1 -1
- package/types/app.d.ts +8 -7
- package/types/app.js.map +1 -1
- package/types/app.mjs.map +1 -1
- package/types/asset-manager.d.ts +4 -4
- package/types/asset-manager.js +2 -2
- package/types/asset-manager.js.map +1 -1
- package/types/asset-manager.mjs +2 -2
- package/types/asset-manager.mjs.map +1 -1
- package/types/async-event-emitter.d.ts +1 -10
- package/types/async-event-emitter.js +0 -5
- package/types/async-event-emitter.js.map +1 -1
- package/types/async-event-emitter.mjs +1 -6
- package/types/async-event-emitter.mjs.map +1 -1
- package/types/client-manager.js +2 -2
- package/types/client-manager.js.map +1 -1
- package/types/client-manager.mjs +2 -2
- package/types/client-manager.mjs.map +1 -1
- package/types/composer.d.ts +40 -25
- package/types/composer.js +114 -40
- package/types/composer.js.map +1 -1
- package/types/composer.mjs +115 -39
- package/types/composer.mjs.map +1 -1
- package/types/config.js.map +1 -1
- package/types/config.mjs.map +1 -1
- package/types/debugging.d.ts +1 -1
- package/types/debugging.js +1 -1
- package/types/debugging.js.map +1 -1
- package/types/debugging.mjs +1 -1
- package/types/debugging.mjs.map +1 -1
- package/types/dispenser-client.js.map +1 -1
- package/types/dispenser-client.mjs.map +1 -1
- package/types/indexer.js.map +1 -1
- package/types/indexer.mjs.map +1 -1
- package/types/kmd-account-manager.js +1 -1
- package/types/kmd-account-manager.js.map +1 -1
- package/types/kmd-account-manager.mjs +2 -2
- package/types/kmd-account-manager.mjs.map +1 -1
- package/types/lifecycle-events.d.ts +10 -0
- package/types/lifecycle-events.js +8 -0
- package/types/lifecycle-events.js.map +1 -0
- package/types/lifecycle-events.mjs +8 -0
- package/types/lifecycle-events.mjs.map +1 -0
- package/types/logging.js.map +1 -1
- package/types/logging.mjs.map +1 -1
- package/types/logic-error.d.ts +2 -3
- package/types/logic-error.js +3 -3
- package/types/logic-error.js.map +1 -1
- package/types/logic-error.mjs +3 -3
- package/types/logic-error.mjs.map +1 -1
- package/types/network-client.js.map +1 -1
- package/types/network-client.mjs.map +1 -1
- package/types/testing.d.ts +1 -1
- package/types/urlTokenBaseHTTPClient.js.map +1 -1
- package/types/urlTokenBaseHTTPClient.mjs.map +1 -1
- package/util.js.map +1 -1
- package/util.mjs.map +1 -1
package/types/app-client.mjs
CHANGED
|
@@ -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 './
|
|
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
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
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.
|
|
342
|
-
this._approvalSourceMap = result.
|
|
420
|
+
if (result.compiledApproval) {
|
|
421
|
+
this._approvalSourceMap = result.compiledApproval.sourceMap;
|
|
343
422
|
}
|
|
344
|
-
if (result.
|
|
345
|
-
this._clearSourceMap = result.
|
|
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
|
-
|
|
360
|
-
return e;
|
|
437
|
+
const { isClearStateProgram, approvalSourceMap, clearSourceMap, program } = details;
|
|
438
|
+
const sourceMap = isClearStateProgram ? clearSourceMap : approvalSourceMap;
|
|
361
439
|
const errorDetails = LogicError.parseLogicError(e);
|
|
362
|
-
|
|
363
|
-
if (errorDetails
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
411
|
-
{ compiledTeal:
|
|
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:
|
|
417
|
-
|
|
418
|
-
clearStateProgram:
|
|
419
|
-
|
|
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
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|