@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.js
CHANGED
|
@@ -11,7 +11,7 @@ var util = require('../util.js');
|
|
|
11
11
|
var types_app = require('./app.js');
|
|
12
12
|
var types_appArc56 = require('./app-arc56.js');
|
|
13
13
|
var types_appSpec = require('./app-spec.js');
|
|
14
|
-
var
|
|
14
|
+
var types_lifecycleEvents = require('./lifecycle-events.js');
|
|
15
15
|
var types_logicError = require('./logic-error.js');
|
|
16
16
|
|
|
17
17
|
var ABIMethod = algosdk.ABIMethod;
|
|
@@ -42,6 +42,57 @@ function getDeployTimeControl(approval, appSpec, templateVariableName, callConfi
|
|
|
42
42
|
return !!abiCallConfig && abiCallConfig !== 'NEVER';
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
+
const BYTE_CBLOCK = 38;
|
|
46
|
+
const INT_CBLOCK = 32;
|
|
47
|
+
/**
|
|
48
|
+
* Get the offset of the last constant block at the beginning of the program
|
|
49
|
+
* This value is used to calculate the program counter for an ARC56 program that has a pcOffsetMethod of "cblocks"
|
|
50
|
+
*
|
|
51
|
+
* @param program The program to parse
|
|
52
|
+
* @returns The PC value of the opcode after the last constant block
|
|
53
|
+
*/
|
|
54
|
+
function getConstantBlockOffset(program) {
|
|
55
|
+
const bytes = [...program];
|
|
56
|
+
const programSize = bytes.length;
|
|
57
|
+
bytes.shift(); // remove version
|
|
58
|
+
/** The PC of the opcode after the bytecblock */
|
|
59
|
+
let bytecblockOffset;
|
|
60
|
+
/** The PC of the opcode after the intcblock */
|
|
61
|
+
let intcblockOffset;
|
|
62
|
+
while (bytes.length > 0) {
|
|
63
|
+
/** The current byte from the beginning of the byte array */
|
|
64
|
+
const byte = bytes.shift();
|
|
65
|
+
// If the byte is a constant block...
|
|
66
|
+
if (byte === BYTE_CBLOCK || byte === INT_CBLOCK) {
|
|
67
|
+
const isBytecblock = byte === BYTE_CBLOCK;
|
|
68
|
+
/** The byte following the opcode is the number of values in the constant block */
|
|
69
|
+
const valuesRemaining = bytes.shift();
|
|
70
|
+
// Iterate over all the values in the constant block
|
|
71
|
+
for (let i = 0; i < valuesRemaining; i++) {
|
|
72
|
+
if (isBytecblock) {
|
|
73
|
+
/** The byte following the opcode is the length of the next element */
|
|
74
|
+
const length = bytes.shift();
|
|
75
|
+
bytes.splice(0, length);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// intcblock is a uvarint, so we need to keep reading until we find the end (MSB is not set)
|
|
79
|
+
while ((bytes.shift() & 0x80) !== 0) {
|
|
80
|
+
// Do nothing...
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (isBytecblock)
|
|
85
|
+
bytecblockOffset = programSize - bytes.length - 1;
|
|
86
|
+
else
|
|
87
|
+
intcblockOffset = programSize - bytes.length - 1;
|
|
88
|
+
if (bytes[0] !== BYTE_CBLOCK && bytes[0] !== INT_CBLOCK) {
|
|
89
|
+
// if the next opcode isn't a constant block, we're done
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return Math.max(bytecblockOffset ?? 0, intcblockOffset ?? 0);
|
|
95
|
+
}
|
|
45
96
|
/** ARC-56/ARC-32 application client that allows you to manage calls and
|
|
46
97
|
* state for a specific deployed instance of an app (with a known app ID). */
|
|
47
98
|
class AppClient {
|
|
@@ -52,6 +103,7 @@ class AppClient {
|
|
|
52
103
|
this._appName = params.appName ?? this._appSpec.name;
|
|
53
104
|
this._algorand = params.algorand;
|
|
54
105
|
this._defaultSender = params.defaultSender;
|
|
106
|
+
this._defaultSigner = params.defaultSigner;
|
|
55
107
|
this._approvalSourceMap = params.approvalSourceMap;
|
|
56
108
|
this._clearSourceMap = params.clearSourceMap;
|
|
57
109
|
this._localStateMethods = (address) => this.getStateMethods(() => this.getLocalState(address), () => this._appSpec.state.keys.local, () => this._appSpec.state.maps.local);
|
|
@@ -73,9 +125,24 @@ class AppClient {
|
|
|
73
125
|
bare: this.getBareSendMethods(),
|
|
74
126
|
};
|
|
75
127
|
}
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Clone this app client with different params
|
|
130
|
+
*
|
|
131
|
+
* @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.
|
|
132
|
+
* @returns A new app client with the altered params
|
|
133
|
+
*/
|
|
134
|
+
clone(params) {
|
|
135
|
+
return new AppClient({
|
|
136
|
+
appId: this._appId,
|
|
137
|
+
appSpec: this._appSpec,
|
|
138
|
+
algorand: this._algorand,
|
|
139
|
+
appName: this._appName,
|
|
140
|
+
defaultSender: this._defaultSender,
|
|
141
|
+
defaultSigner: this._defaultSigner,
|
|
142
|
+
approvalSourceMap: this._approvalSourceMap,
|
|
143
|
+
clearSourceMap: this._clearSourceMap,
|
|
144
|
+
...params,
|
|
145
|
+
});
|
|
79
146
|
}
|
|
80
147
|
/**
|
|
81
148
|
* Returns a new `AppClient` client, resolving the app by creator address and name
|
|
@@ -147,6 +214,10 @@ class AppClient {
|
|
|
147
214
|
get appSpec() {
|
|
148
215
|
return this._appSpec;
|
|
149
216
|
}
|
|
217
|
+
/** A reference to the underlying `AlgorandClient` this app client is using. */
|
|
218
|
+
get algorand() {
|
|
219
|
+
return this._algorand;
|
|
220
|
+
}
|
|
150
221
|
/** Get parameters to create transactions for the current app.
|
|
151
222
|
*
|
|
152
223
|
* A good mental model for this is that these parameters represent a deferred transaction creation.
|
|
@@ -278,11 +349,19 @@ class AppClient {
|
|
|
278
349
|
* @param isClearStateProgram Whether or not the code was running the clear state program (defaults to approval program)
|
|
279
350
|
* @returns The new error, or if there was no logic error or source map then the wrapped error with source details
|
|
280
351
|
*/
|
|
281
|
-
exposeLogicError(e, isClearStateProgram) {
|
|
352
|
+
async exposeLogicError(e, isClearStateProgram) {
|
|
353
|
+
const pcOffsetMethod = this._appSpec.sourceInfo?.[isClearStateProgram ? 'clear' : 'approval']?.pcOffsetMethod;
|
|
354
|
+
let program;
|
|
355
|
+
if (pcOffsetMethod === 'cblocks') {
|
|
356
|
+
// TODO: Cache this if we deploy the app and it's not updateable
|
|
357
|
+
const appInfo = await this._algorand.app.getById(this.appId);
|
|
358
|
+
program = isClearStateProgram ? appInfo.clearStateProgram : appInfo.approvalProgram;
|
|
359
|
+
}
|
|
282
360
|
return AppClient.exposeLogicError(e, this._appSpec, {
|
|
283
361
|
isClearStateProgram,
|
|
284
362
|
approvalSourceMap: this._approvalSourceMap,
|
|
285
363
|
clearSourceMap: this._clearSourceMap,
|
|
364
|
+
program,
|
|
286
365
|
});
|
|
287
366
|
}
|
|
288
367
|
/**
|
|
@@ -340,11 +419,11 @@ class AppClient {
|
|
|
340
419
|
*/
|
|
341
420
|
async compile(compilation) {
|
|
342
421
|
const result = await AppClient.compile(this._appSpec, this._algorand.app, compilation);
|
|
343
|
-
if (result.
|
|
344
|
-
this._approvalSourceMap = result.
|
|
422
|
+
if (result.compiledApproval) {
|
|
423
|
+
this._approvalSourceMap = result.compiledApproval.sourceMap;
|
|
345
424
|
}
|
|
346
|
-
if (result.
|
|
347
|
-
this._clearSourceMap = result.
|
|
425
|
+
if (result.compiledClear) {
|
|
426
|
+
this._clearSourceMap = result.compiledClear.sourceMap;
|
|
348
427
|
}
|
|
349
428
|
return result;
|
|
350
429
|
}
|
|
@@ -357,17 +436,45 @@ class AppClient {
|
|
|
357
436
|
* @returns The new error, or if there was no logic error or source map then the wrapped error with source details
|
|
358
437
|
*/
|
|
359
438
|
static exposeLogicError(e, appSpec, details) {
|
|
360
|
-
const { isClearStateProgram, approvalSourceMap, clearSourceMap } = details;
|
|
361
|
-
|
|
362
|
-
return e;
|
|
439
|
+
const { isClearStateProgram, approvalSourceMap, clearSourceMap, program } = details;
|
|
440
|
+
const sourceMap = isClearStateProgram ? clearSourceMap : approvalSourceMap;
|
|
363
441
|
const errorDetails = types_logicError.LogicError.parseLogicError(e);
|
|
364
|
-
|
|
365
|
-
if (errorDetails
|
|
442
|
+
// Return the error if we don't have a PC
|
|
443
|
+
if (errorDetails === undefined || errorDetails?.pc === undefined)
|
|
444
|
+
return e;
|
|
445
|
+
/** The PC value to find in the ARC56 SourceInfo */
|
|
446
|
+
let arc56Pc = errorDetails?.pc;
|
|
447
|
+
const programSourceInfo = isClearStateProgram ? appSpec.sourceInfo?.clear : appSpec.sourceInfo?.approval;
|
|
448
|
+
/** The offset to apply to the PC if using the cblocks pc offset method */
|
|
449
|
+
let cblocksOffset = 0;
|
|
450
|
+
// If the program uses cblocks offset, then we need to adjust the PC accordingly
|
|
451
|
+
if (programSourceInfo?.pcOffsetMethod === 'cblocks') {
|
|
452
|
+
if (program === undefined)
|
|
453
|
+
throw new Error('Program bytes are required to calculate the ARC56 cblocks PC offset');
|
|
454
|
+
cblocksOffset = getConstantBlockOffset(program);
|
|
455
|
+
arc56Pc = errorDetails.pc - cblocksOffset;
|
|
456
|
+
}
|
|
457
|
+
// Find the source info for this PC and get the error message
|
|
458
|
+
const sourceInfo = programSourceInfo?.sourceInfo.find((s) => s.pc.includes(arc56Pc));
|
|
459
|
+
const errorMessage = sourceInfo?.errorMessage;
|
|
460
|
+
// If we have the source we can display the TEAL in the error message
|
|
461
|
+
if (appSpec.source) {
|
|
462
|
+
let getLineForPc = (inputPc) => sourceMap?.getLineForPc?.(inputPc);
|
|
463
|
+
// If the SourceMap is not defined, we need to provide our own function for going from a PC to TEAL based on ARC56 SourceInfo[]
|
|
464
|
+
if (sourceMap === undefined) {
|
|
465
|
+
getLineForPc = (inputPc) => {
|
|
466
|
+
const teal = programSourceInfo?.sourceInfo.find((s) => s.pc.includes(inputPc - cblocksOffset))?.teal;
|
|
467
|
+
if (teal === undefined)
|
|
468
|
+
return undefined;
|
|
469
|
+
return teal - 1;
|
|
470
|
+
};
|
|
471
|
+
}
|
|
366
472
|
e = new types_logicError.LogicError(errorDetails, buffer.Buffer.from(isClearStateProgram ? appSpec.source.clear : appSpec.source.approval, 'base64')
|
|
367
473
|
.toString()
|
|
368
474
|
.split('\n'),
|
|
369
475
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
370
|
-
|
|
476
|
+
getLineForPc);
|
|
477
|
+
}
|
|
371
478
|
if (errorMessage) {
|
|
372
479
|
const appId = JSON.stringify(e).match(/(?<=app=)\d+/)?.[0] || '';
|
|
373
480
|
const txId = JSON.stringify(e).match(/(?<=transaction )\S+(?=:)/)?.[0];
|
|
@@ -400,25 +507,25 @@ class AppClient {
|
|
|
400
507
|
};
|
|
401
508
|
}
|
|
402
509
|
const approvalTemplate = buffer.Buffer.from(appSpec.source.approval, 'base64').toString('utf-8');
|
|
403
|
-
const
|
|
510
|
+
const compiledApproval = await appManager.compileTealTemplate(approvalTemplate, deployTimeParams, {
|
|
404
511
|
updatable,
|
|
405
512
|
deletable,
|
|
406
513
|
});
|
|
407
514
|
const clearTemplate = buffer.Buffer.from(appSpec.source.clear, 'base64').toString('utf-8');
|
|
408
|
-
const
|
|
515
|
+
const compiledClear = await appManager.compileTealTemplate(clearTemplate, deployTimeParams);
|
|
409
516
|
if (config.Config.debug) {
|
|
410
|
-
await config.Config.events.emitAsync(
|
|
517
|
+
await config.Config.events.emitAsync(types_lifecycleEvents.EventType.AppCompiled, {
|
|
411
518
|
sources: [
|
|
412
|
-
{ compiledTeal:
|
|
413
|
-
{ compiledTeal:
|
|
519
|
+
{ compiledTeal: compiledApproval, appName: appSpec.name, fileName: 'approval' },
|
|
520
|
+
{ compiledTeal: compiledClear, appName: appSpec.name, fileName: 'clear' },
|
|
414
521
|
],
|
|
415
522
|
});
|
|
416
523
|
}
|
|
417
524
|
return {
|
|
418
|
-
approvalProgram:
|
|
419
|
-
|
|
420
|
-
clearStateProgram:
|
|
421
|
-
|
|
525
|
+
approvalProgram: compiledApproval.compiledBase64ToBytes,
|
|
526
|
+
compiledApproval,
|
|
527
|
+
clearStateProgram: compiledClear.compiledBase64ToBytes,
|
|
528
|
+
compiledClear,
|
|
422
529
|
};
|
|
423
530
|
}
|
|
424
531
|
/**
|
|
@@ -444,19 +551,22 @@ class AppClient {
|
|
|
444
551
|
if (defaultValue) {
|
|
445
552
|
switch (defaultValue.source) {
|
|
446
553
|
case 'literal':
|
|
447
|
-
if (typeof defaultValue.data === 'number')
|
|
448
|
-
return defaultValue.data;
|
|
449
554
|
return types_appArc56.getABIDecodedValue(buffer.Buffer.from(defaultValue.data, 'base64'), m.method.args[i].defaultValue?.type ?? m.method.args[i].type, this._appSpec.structs);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
555
|
+
case 'method': {
|
|
556
|
+
const method = this.getABIMethod(defaultValue.data);
|
|
557
|
+
const result = await this.send.call({
|
|
558
|
+
method: defaultValue.data,
|
|
559
|
+
args: method.args.map(() => undefined),
|
|
560
|
+
sender,
|
|
561
|
+
});
|
|
562
|
+
if (result.return === undefined) {
|
|
563
|
+
throw new Error('Default value method call did not return a value');
|
|
564
|
+
}
|
|
565
|
+
if (typeof result.return === 'object' && !(result.return instanceof Uint8Array) && !Array.isArray(result.return)) {
|
|
566
|
+
return types_appArc56.getABITupleFromABIStruct(result.return, this._appSpec.structs[method.returns.struct], this._appSpec.structs);
|
|
567
|
+
}
|
|
568
|
+
return result.return;
|
|
569
|
+
}
|
|
460
570
|
case 'local':
|
|
461
571
|
case 'global': {
|
|
462
572
|
const state = defaultValue.source === 'global' ? await this.getGlobalState() : await this.getLocalState(sender);
|
|
@@ -474,7 +584,9 @@ class AppClient {
|
|
|
474
584
|
}
|
|
475
585
|
}
|
|
476
586
|
}
|
|
477
|
-
|
|
587
|
+
if (!algosdk.abiTypeIsTransaction(arg.type)) {
|
|
588
|
+
throw new Error(`No value provided for required argument ${arg.name ?? `arg${i + 1}`} in call to method ${m.name}`);
|
|
589
|
+
}
|
|
478
590
|
}) ?? []);
|
|
479
591
|
}
|
|
480
592
|
getBareParamsMethods() {
|
|
@@ -543,10 +655,7 @@ class AppClient {
|
|
|
543
655
|
const compiled = await this.compile(params);
|
|
544
656
|
return {
|
|
545
657
|
...(await this.handleCallErrors(async () => this._algorand.send.appUpdate(await this.params.bare.update(params)))),
|
|
546
|
-
...
|
|
547
|
-
compiledApproval: compiled.approvalProgramCompilationResult,
|
|
548
|
-
compiledClear: compiled.clearStateProgramCompilationResult,
|
|
549
|
-
},
|
|
658
|
+
...compiled,
|
|
550
659
|
};
|
|
551
660
|
},
|
|
552
661
|
/** Signs and sends an opt-in call */
|
|
@@ -578,6 +687,7 @@ class AppClient {
|
|
|
578
687
|
return {
|
|
579
688
|
...params,
|
|
580
689
|
sender: this.getSender(params.sender),
|
|
690
|
+
signer: this.getSigner(params.sender, params.signer),
|
|
581
691
|
receiver: this.appAddress,
|
|
582
692
|
};
|
|
583
693
|
},
|
|
@@ -619,10 +729,7 @@ class AppClient {
|
|
|
619
729
|
const compiled = await this.compile(params);
|
|
620
730
|
return {
|
|
621
731
|
...(await this.handleCallErrors(async () => this.processMethodCallReturn(this._algorand.send.appUpdateMethodCall(await this.params.update({ ...params })), types_appArc56.getArc56Method(params.method, this._appSpec)))),
|
|
622
|
-
...
|
|
623
|
-
compiledApproval: compiled.approvalProgramCompilationResult,
|
|
624
|
-
compiledClear: compiled.clearStateProgramCompilationResult,
|
|
625
|
-
},
|
|
732
|
+
...compiled,
|
|
626
733
|
};
|
|
627
734
|
},
|
|
628
735
|
/**
|
|
@@ -648,13 +755,15 @@ class AppClient {
|
|
|
648
755
|
*/
|
|
649
756
|
call: async (params) => {
|
|
650
757
|
// Read-only call - do it via simulate
|
|
651
|
-
if (params.onComplete === OnApplicationComplete.NoOpOC ||
|
|
652
|
-
|
|
758
|
+
if ((params.onComplete === OnApplicationComplete.NoOpOC || !params.onComplete) &&
|
|
759
|
+
types_appArc56.getArc56Method(params.method, this._appSpec).method.readonly) {
|
|
653
760
|
const result = await this._algorand
|
|
654
761
|
.newGroup()
|
|
655
762
|
.addAppCallMethodCall(await this.params.call(params))
|
|
656
763
|
.simulate({
|
|
657
|
-
allowUnnamedResources: params.populateAppCallResources,
|
|
764
|
+
allowUnnamedResources: params.populateAppCallResources ?? true,
|
|
765
|
+
// Simulate calls for a readonly method shouldn't invoke signing
|
|
766
|
+
skipSignatures: true,
|
|
658
767
|
});
|
|
659
768
|
return this.processMethodCallReturn({
|
|
660
769
|
...result,
|
|
@@ -706,7 +815,7 @@ class AppClient {
|
|
|
706
815
|
},
|
|
707
816
|
};
|
|
708
817
|
}
|
|
709
|
-
/** Returns the sender for a call, using the `defaultSender`
|
|
818
|
+
/** Returns the sender for a call, using the provided sender or using the `defaultSender`
|
|
710
819
|
* if none provided and throws an error if neither provided */
|
|
711
820
|
getSender(sender) {
|
|
712
821
|
if (!sender && !this._defaultSender) {
|
|
@@ -714,11 +823,18 @@ class AppClient {
|
|
|
714
823
|
}
|
|
715
824
|
return sender ?? this._defaultSender;
|
|
716
825
|
}
|
|
826
|
+
/** Returns the signer for a call, using the provided signer or the `defaultSigner`
|
|
827
|
+
* if no signer was provided and the call will use default sender
|
|
828
|
+
* or `undefined` otherwise (so the signer is resolved from `AlgorandClient`) */
|
|
829
|
+
getSigner(sender, signer) {
|
|
830
|
+
return signer ?? (!sender ? this._defaultSigner : undefined);
|
|
831
|
+
}
|
|
717
832
|
getBareParams(params, onComplete) {
|
|
718
833
|
return {
|
|
719
834
|
...params,
|
|
720
835
|
appId: this._appId,
|
|
721
836
|
sender: this.getSender(params?.sender),
|
|
837
|
+
signer: this.getSigner(params?.sender, params?.signer),
|
|
722
838
|
onComplete,
|
|
723
839
|
};
|
|
724
840
|
}
|
|
@@ -730,6 +846,7 @@ class AppClient {
|
|
|
730
846
|
...params,
|
|
731
847
|
appId: this._appId,
|
|
732
848
|
sender: sender,
|
|
849
|
+
signer: this.getSigner(params.sender, params.signer),
|
|
733
850
|
method,
|
|
734
851
|
onComplete,
|
|
735
852
|
args,
|
|
@@ -741,7 +858,7 @@ class AppClient {
|
|
|
741
858
|
return await call();
|
|
742
859
|
}
|
|
743
860
|
catch (e) {
|
|
744
|
-
throw this.exposeLogicError(e);
|
|
861
|
+
throw await this.exposeLogicError(e);
|
|
745
862
|
}
|
|
746
863
|
}
|
|
747
864
|
getBoxMethods() {
|
|
@@ -945,7 +1062,7 @@ class ApplicationClient {
|
|
|
945
1062
|
const clearCompiled = await app.compileTeal(clear, this.algod);
|
|
946
1063
|
this._clearSourceMap = clearCompiled?.sourceMap;
|
|
947
1064
|
if (config.Config.debug) {
|
|
948
|
-
await config.Config.events.emitAsync(
|
|
1065
|
+
await config.Config.events.emitAsync(types_lifecycleEvents.EventType.AppCompiled, {
|
|
949
1066
|
sources: [
|
|
950
1067
|
{ compiledTeal: approvalCompiled, appName: this._appName, fileName: 'approval' },
|
|
951
1068
|
{ compiledTeal: clearCompiled, appName: this._appName, fileName: 'clear' },
|
|
@@ -1105,7 +1222,7 @@ class ApplicationClient {
|
|
|
1105
1222
|
return { ...result, ...{ compiledApproval: approvalCompiled, compiledClear: clearCompiled } };
|
|
1106
1223
|
}
|
|
1107
1224
|
catch (e) {
|
|
1108
|
-
throw this.exposeLogicError(e);
|
|
1225
|
+
throw await this.exposeLogicError(e);
|
|
1109
1226
|
}
|
|
1110
1227
|
}
|
|
1111
1228
|
/**
|
|
@@ -1139,7 +1256,7 @@ class ApplicationClient {
|
|
|
1139
1256
|
return { ...result, ...{ compiledApproval: approvalCompiled, compiledClear: clearCompiled } };
|
|
1140
1257
|
}
|
|
1141
1258
|
catch (e) {
|
|
1142
|
-
throw this.exposeLogicError(e);
|
|
1259
|
+
throw await this.exposeLogicError(e);
|
|
1143
1260
|
}
|
|
1144
1261
|
}
|
|
1145
1262
|
/**
|
|
@@ -1492,7 +1609,7 @@ class ApplicationClient {
|
|
|
1492
1609
|
.toString()
|
|
1493
1610
|
.split('\n'),
|
|
1494
1611
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1495
|
-
isClear ? this._clearSourceMap : this._approvalSourceMap);
|
|
1612
|
+
(pc) => (isClear ? this._clearSourceMap : this._approvalSourceMap).getLineForPc(pc));
|
|
1496
1613
|
else
|
|
1497
1614
|
return e;
|
|
1498
1615
|
}
|