@algorandfoundation/algokit-utils 7.0.0-beta.9 → 7.0.1
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 +9 -2
- 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 +21 -10
- package/types/app-client.js +143 -36
- package/types/app-client.js.map +1 -1
- package/types/app-client.mjs +141 -34
- 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 +32 -21
- package/types/app-factory.js +8 -2
- package/types/app-factory.js.map +1 -1
- package/types/app-factory.mjs +8 -2
- 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 +56 -30
- package/types/composer.js +103 -47
- package/types/composer.js.map +1 -1
- package/types/composer.mjs +104 -46
- package/types/composer.mjs.map +1 -1
- package/types/config.d.ts +0 -4
- 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/transaction.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.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import { TransactionSignerAccount } from './account';
|
|
|
3
3
|
import { AlgorandClientInterface } from './algorand-client-interface';
|
|
4
4
|
import { AlgoAmount } from './amount';
|
|
5
5
|
import { ABIAppCallArgs, ABIReturn, AppCallArgs, AppCallTransactionResult, AppCallType, AppCompilationResult, AppMetadata, AppReference, AppReturn, AppState, AppStorageSchema, BoxName, AppLookup as LegacyAppLookup, OnSchemaBreak, OnUpdate, RawAppCallArgs, SendAppTransactionResult, TealTemplateParams } from './app';
|
|
6
|
-
import { ABIStruct, Arc56Contract, Arc56Method } from './app-arc56';
|
|
6
|
+
import { ABIStruct, Arc56Contract, Arc56Method, ProgramSourceInfo } from './app-arc56';
|
|
7
7
|
import { AppLookup } from './app-deployer';
|
|
8
8
|
import { AppManager, BoxIdentifier } from './app-manager';
|
|
9
9
|
import { AppSpec } from './app-spec';
|
|
10
|
-
import
|
|
10
|
+
import { AppCallMethodCall, AppCallParams, AppDeleteMethodCall, AppDeleteParams, AppMethodCall, AppMethodCallTransactionArgument, CommonAppCallParams, PaymentParams } from './composer';
|
|
11
11
|
import { Expand } from './expand';
|
|
12
12
|
import { SendParams, SendTransactionFrom, SendTransactionParams, TransactionNote } from './transaction';
|
|
13
13
|
import ABIMethod = algosdk.ABIMethod;
|
|
@@ -114,8 +114,7 @@ export interface AppClientDeployParams extends AppClientDeployCoreParams, AppCli
|
|
|
114
114
|
/** Any overrides for the storage schema to request for the created app; by default the schema indicated by the app spec is used. */
|
|
115
115
|
schema?: Partial<AppStorageSchema>;
|
|
116
116
|
}
|
|
117
|
-
export
|
|
118
|
-
}
|
|
117
|
+
export type AppClientCallRawArgs = RawAppCallArgs;
|
|
119
118
|
export interface AppClientCallABIArgs extends Omit<ABIAppCallArgs, 'method'> {
|
|
120
119
|
/** If calling an ABI method then either the name of the method, or the ABI signature */
|
|
121
120
|
method: string;
|
|
@@ -215,6 +214,8 @@ export interface AppClientParams {
|
|
|
215
214
|
/** Optional source map for the clear state program */
|
|
216
215
|
clearSourceMap?: SourceMap;
|
|
217
216
|
}
|
|
217
|
+
/** Parameters to clone an app client */
|
|
218
|
+
export type CloneAppClientParams = Expand<Partial<Omit<AppClientParams, 'algorand' | 'appSpec'>>>;
|
|
218
219
|
/** onComplete parameter for a non-update app call */
|
|
219
220
|
export type CallOnComplete = {
|
|
220
221
|
/** On-complete of the call; defaults to no-op */
|
|
@@ -243,6 +244,7 @@ export type AppClientMethodCallParams = Expand<Omit<CommonAppCallParams, 'appId'
|
|
|
243
244
|
* * A transaction (where the signer will be automatically assigned)
|
|
244
245
|
* * An unawaited transaction (e.g. from algorand.createTransaction.transactionType())
|
|
245
246
|
* * Another method call (via method call params object)
|
|
247
|
+
* * undefined (this represents a placeholder for either a default argument or a transaction argument that is fulfilled by another method call argument)
|
|
246
248
|
*/
|
|
247
249
|
args?: (ABIValue | ABIStruct | AppMethodCallTransactionArgument | undefined)[];
|
|
248
250
|
}>;
|
|
@@ -283,8 +285,13 @@ export declare class AppClient {
|
|
|
283
285
|
private _createTransactionsMethods;
|
|
284
286
|
private _sendMethods;
|
|
285
287
|
constructor(params: AppClientParams);
|
|
286
|
-
/**
|
|
287
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Clone this app client with different params
|
|
290
|
+
*
|
|
291
|
+
* @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.
|
|
292
|
+
* @returns A new app client with the altered params
|
|
293
|
+
*/
|
|
294
|
+
clone(params: CloneAppClientParams): AppClient;
|
|
288
295
|
/**
|
|
289
296
|
* Returns a new `AppClient` client, resolving the app by creator address and name
|
|
290
297
|
* using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note).
|
|
@@ -474,7 +481,7 @@ export declare class AppClient {
|
|
|
474
481
|
boxReferences?: (BoxIdentifier | import("./app-manager").BoxReference)[] | undefined;
|
|
475
482
|
approvalProgram: string | Uint8Array;
|
|
476
483
|
clearStateProgram: string | Uint8Array;
|
|
477
|
-
}> | AppMethodCall<import("./composer").AppMethodCallParams>)[] | undefined;
|
|
484
|
+
}> | AppMethodCall<import("./composer").AppMethodCallParams> | undefined)[] | undefined;
|
|
478
485
|
}>;
|
|
479
486
|
/** Return params for an opt-in ABI call */
|
|
480
487
|
optIn: (params: {
|
|
@@ -1511,7 +1518,7 @@ export declare class AppClient {
|
|
|
1511
1518
|
* @param isClearStateProgram Whether or not the code was running the clear state program (defaults to approval program)
|
|
1512
1519
|
* @returns The new error, or if there was no logic error or source map then the wrapped error with source details
|
|
1513
1520
|
*/
|
|
1514
|
-
exposeLogicError(e: Error, isClearStateProgram?: boolean): Error
|
|
1521
|
+
exposeLogicError(e: Error, isClearStateProgram?: boolean): Promise<Error>;
|
|
1515
1522
|
/**
|
|
1516
1523
|
* Export the current source maps for the app.
|
|
1517
1524
|
* @returns The source maps
|
|
@@ -1562,6 +1569,9 @@ export declare class AppClient {
|
|
|
1562
1569
|
/** Whether or not the code was running the clear state program (defaults to approval program) */ isClearStateProgram?: boolean;
|
|
1563
1570
|
/** Approval program source map */ approvalSourceMap?: SourceMap;
|
|
1564
1571
|
/** Clear state program source map */ clearSourceMap?: SourceMap;
|
|
1572
|
+
/** program bytes */ program?: Uint8Array;
|
|
1573
|
+
/** ARC56 approval source info */ approvalSourceInfo?: ProgramSourceInfo;
|
|
1574
|
+
/** ARC56 clear source info */ clearSourceInfo?: ProgramSourceInfo;
|
|
1565
1575
|
}): Error;
|
|
1566
1576
|
/**
|
|
1567
1577
|
* Compiles the approval and clear state programs (if TEAL templates provided),
|
|
@@ -1595,7 +1605,7 @@ export declare class AppClient {
|
|
|
1595
1605
|
* if none provided and throws an error if neither provided */
|
|
1596
1606
|
private getSender;
|
|
1597
1607
|
/** Returns the signer for a call, using the provided signer or the `defaultSigner`
|
|
1598
|
-
* if no signer was provided and the call will use default
|
|
1608
|
+
* if no signer was provided and the sender resolves to the default sender, the call will use default signer
|
|
1599
1609
|
* or `undefined` otherwise (so the signer is resolved from `AlgorandClient`) */
|
|
1600
1610
|
private getSigner;
|
|
1601
1611
|
private getBareParams;
|
|
@@ -1691,6 +1701,7 @@ export declare class ApplicationClient {
|
|
|
1691
1701
|
deletable?: boolean | undefined;
|
|
1692
1702
|
updatable?: boolean | undefined;
|
|
1693
1703
|
return?: ABIReturn | undefined;
|
|
1704
|
+
/** Configuration to resolve app by creator and name `getCreatorAppsByName` */
|
|
1694
1705
|
operationPerformed: "update" | "create";
|
|
1695
1706
|
} | {
|
|
1696
1707
|
compiledApproval: import("./app").CompiledTeal;
|
|
@@ -1711,7 +1722,7 @@ export declare class ApplicationClient {
|
|
|
1711
1722
|
updatable?: boolean | undefined;
|
|
1712
1723
|
return?: ABIReturn | undefined;
|
|
1713
1724
|
deleteReturn?: ABIReturn | undefined;
|
|
1714
|
-
deleteResult: import("./transaction").ConfirmedTransactionResult;
|
|
1725
|
+
deleteResult: import("./transaction").ConfirmedTransactionResult;
|
|
1715
1726
|
operationPerformed: "replace";
|
|
1716
1727
|
}>;
|
|
1717
1728
|
/**
|
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 {
|
|
@@ -74,9 +125,24 @@ class AppClient {
|
|
|
74
125
|
bare: this.getBareSendMethods(),
|
|
75
126
|
};
|
|
76
127
|
}
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
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
|
+
});
|
|
80
146
|
}
|
|
81
147
|
/**
|
|
82
148
|
* Returns a new `AppClient` client, resolving the app by creator address and name
|
|
@@ -283,11 +349,19 @@ class AppClient {
|
|
|
283
349
|
* @param isClearStateProgram Whether or not the code was running the clear state program (defaults to approval program)
|
|
284
350
|
* @returns The new error, or if there was no logic error or source map then the wrapped error with source details
|
|
285
351
|
*/
|
|
286
|
-
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
|
+
}
|
|
287
360
|
return AppClient.exposeLogicError(e, this._appSpec, {
|
|
288
361
|
isClearStateProgram,
|
|
289
362
|
approvalSourceMap: this._approvalSourceMap,
|
|
290
363
|
clearSourceMap: this._clearSourceMap,
|
|
364
|
+
program,
|
|
291
365
|
});
|
|
292
366
|
}
|
|
293
367
|
/**
|
|
@@ -362,17 +436,45 @@ class AppClient {
|
|
|
362
436
|
* @returns The new error, or if there was no logic error or source map then the wrapped error with source details
|
|
363
437
|
*/
|
|
364
438
|
static exposeLogicError(e, appSpec, details) {
|
|
365
|
-
const { isClearStateProgram, approvalSourceMap, clearSourceMap } = details;
|
|
366
|
-
|
|
367
|
-
return e;
|
|
439
|
+
const { isClearStateProgram, approvalSourceMap, clearSourceMap, program } = details;
|
|
440
|
+
const sourceMap = isClearStateProgram ? clearSourceMap : approvalSourceMap;
|
|
368
441
|
const errorDetails = types_logicError.LogicError.parseLogicError(e);
|
|
369
|
-
|
|
370
|
-
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
|
+
}
|
|
371
472
|
e = new types_logicError.LogicError(errorDetails, buffer.Buffer.from(isClearStateProgram ? appSpec.source.clear : appSpec.source.approval, 'base64')
|
|
372
473
|
.toString()
|
|
373
474
|
.split('\n'),
|
|
374
475
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
375
|
-
|
|
476
|
+
getLineForPc);
|
|
477
|
+
}
|
|
376
478
|
if (errorMessage) {
|
|
377
479
|
const appId = JSON.stringify(e).match(/(?<=app=)\d+/)?.[0] || '';
|
|
378
480
|
const txId = JSON.stringify(e).match(/(?<=transaction )\S+(?=:)/)?.[0];
|
|
@@ -412,7 +514,7 @@ class AppClient {
|
|
|
412
514
|
const clearTemplate = buffer.Buffer.from(appSpec.source.clear, 'base64').toString('utf-8');
|
|
413
515
|
const compiledClear = await appManager.compileTealTemplate(clearTemplate, deployTimeParams);
|
|
414
516
|
if (config.Config.debug) {
|
|
415
|
-
await config.Config.events.emitAsync(
|
|
517
|
+
await config.Config.events.emitAsync(types_lifecycleEvents.EventType.AppCompiled, {
|
|
416
518
|
sources: [
|
|
417
519
|
{ compiledTeal: compiledApproval, appName: appSpec.name, fileName: 'approval' },
|
|
418
520
|
{ compiledTeal: compiledClear, appName: appSpec.name, fileName: 'clear' },
|
|
@@ -449,19 +551,22 @@ class AppClient {
|
|
|
449
551
|
if (defaultValue) {
|
|
450
552
|
switch (defaultValue.source) {
|
|
451
553
|
case 'literal':
|
|
452
|
-
if (typeof defaultValue.data === 'number')
|
|
453
|
-
return defaultValue.data;
|
|
454
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);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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
|
+
}
|
|
465
570
|
case 'local':
|
|
466
571
|
case 'global': {
|
|
467
572
|
const state = defaultValue.source === 'global' ? await this.getGlobalState() : await this.getLocalState(sender);
|
|
@@ -479,7 +584,9 @@ class AppClient {
|
|
|
479
584
|
}
|
|
480
585
|
}
|
|
481
586
|
}
|
|
482
|
-
|
|
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
|
+
}
|
|
483
590
|
}) ?? []);
|
|
484
591
|
}
|
|
485
592
|
getBareParamsMethods() {
|
|
@@ -648,13 +755,13 @@ 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,
|
|
658
765
|
// Simulate calls for a readonly method shouldn't invoke signing
|
|
659
766
|
skipSignatures: true,
|
|
660
767
|
});
|
|
@@ -712,15 +819,15 @@ class AppClient {
|
|
|
712
819
|
* if none provided and throws an error if neither provided */
|
|
713
820
|
getSender(sender) {
|
|
714
821
|
if (!sender && !this._defaultSender) {
|
|
715
|
-
throw new Error(`No sender provided and no default sender present in app
|
|
822
|
+
throw new Error(`No sender provided and no default sender present in app factory for call to app ${this._appName}`);
|
|
716
823
|
}
|
|
717
824
|
return sender ?? this._defaultSender;
|
|
718
825
|
}
|
|
719
826
|
/** Returns the signer for a call, using the provided signer or the `defaultSigner`
|
|
720
|
-
* if no signer was provided and the call will use default
|
|
827
|
+
* if no signer was provided and the sender resolves to the default sender, the call will use default signer
|
|
721
828
|
* or `undefined` otherwise (so the signer is resolved from `AlgorandClient`) */
|
|
722
829
|
getSigner(sender, signer) {
|
|
723
|
-
return signer ?? (!sender ? this._defaultSigner : undefined);
|
|
830
|
+
return signer ?? (!sender || sender === this._defaultSender ? this._defaultSigner : undefined);
|
|
724
831
|
}
|
|
725
832
|
getBareParams(params, onComplete) {
|
|
726
833
|
return {
|
|
@@ -751,7 +858,7 @@ class AppClient {
|
|
|
751
858
|
return await call();
|
|
752
859
|
}
|
|
753
860
|
catch (e) {
|
|
754
|
-
throw this.exposeLogicError(e);
|
|
861
|
+
throw await this.exposeLogicError(e);
|
|
755
862
|
}
|
|
756
863
|
}
|
|
757
864
|
getBoxMethods() {
|
|
@@ -955,7 +1062,7 @@ class ApplicationClient {
|
|
|
955
1062
|
const clearCompiled = await app.compileTeal(clear, this.algod);
|
|
956
1063
|
this._clearSourceMap = clearCompiled?.sourceMap;
|
|
957
1064
|
if (config.Config.debug) {
|
|
958
|
-
await config.Config.events.emitAsync(
|
|
1065
|
+
await config.Config.events.emitAsync(types_lifecycleEvents.EventType.AppCompiled, {
|
|
959
1066
|
sources: [
|
|
960
1067
|
{ compiledTeal: approvalCompiled, appName: this._appName, fileName: 'approval' },
|
|
961
1068
|
{ compiledTeal: clearCompiled, appName: this._appName, fileName: 'clear' },
|
|
@@ -1115,7 +1222,7 @@ class ApplicationClient {
|
|
|
1115
1222
|
return { ...result, ...{ compiledApproval: approvalCompiled, compiledClear: clearCompiled } };
|
|
1116
1223
|
}
|
|
1117
1224
|
catch (e) {
|
|
1118
|
-
throw this.exposeLogicError(e);
|
|
1225
|
+
throw await this.exposeLogicError(e);
|
|
1119
1226
|
}
|
|
1120
1227
|
}
|
|
1121
1228
|
/**
|
|
@@ -1149,7 +1256,7 @@ class ApplicationClient {
|
|
|
1149
1256
|
return { ...result, ...{ compiledApproval: approvalCompiled, compiledClear: clearCompiled } };
|
|
1150
1257
|
}
|
|
1151
1258
|
catch (e) {
|
|
1152
|
-
throw this.exposeLogicError(e);
|
|
1259
|
+
throw await this.exposeLogicError(e);
|
|
1153
1260
|
}
|
|
1154
1261
|
}
|
|
1155
1262
|
/**
|
|
@@ -1502,7 +1609,7 @@ class ApplicationClient {
|
|
|
1502
1609
|
.toString()
|
|
1503
1610
|
.split('\n'),
|
|
1504
1611
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1505
|
-
isClear ? this._clearSourceMap : this._approvalSourceMap);
|
|
1612
|
+
(pc) => (isClear ? this._clearSourceMap : this._approvalSourceMap).getLineForPc(pc));
|
|
1506
1613
|
else
|
|
1507
1614
|
return e;
|
|
1508
1615
|
}
|