@algorandfoundation/algorand-typescript-testing 1.0.0 → 1.0.2-beta.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.
Files changed (123) hide show
  1. package/README.md +307 -0
  2. package/abi-metadata.d.ts +3 -15
  3. package/application-spy.d.ts +32 -0
  4. package/arc4-DZBwKOPQ.js +143 -0
  5. package/arc4-DZBwKOPQ.js.map +1 -0
  6. package/asset-params-BwXtTjOo.js +1421 -0
  7. package/asset-params-BwXtTjOo.js.map +1 -0
  8. package/collections/custom-key-map.d.ts +4 -9
  9. package/constants.d.ts +1 -26
  10. package/context-helpers/context-manager.d.ts +1 -0
  11. package/context-helpers/context-util.d.ts +1 -0
  12. package/context-helpers/internal-context.d.ts +0 -25
  13. package/decode-logs.d.ts +0 -2
  14. package/errors.d.ts +28 -2
  15. package/impl/acct-params.d.ts +1 -5
  16. package/impl/app-global.d.ts +1 -2
  17. package/impl/app-local.d.ts +1 -2
  18. package/impl/app-params.d.ts +1 -3
  19. package/impl/asset-holding.d.ts +1 -2
  20. package/impl/asset-params.d.ts +1 -3
  21. package/impl/base-32.d.ts +1 -0
  22. package/impl/base-contract.d.ts +1 -0
  23. package/impl/base.d.ts +1 -18
  24. package/impl/block.d.ts +13 -2
  25. package/impl/box.d.ts +1 -2
  26. package/impl/c2c.d.ts +1 -0
  27. package/impl/clone.d.ts +1 -0
  28. package/impl/compiled.d.ts +1 -0
  29. package/impl/contract.d.ts +1 -0
  30. package/impl/crypto.d.ts +1 -12
  31. package/impl/emit.d.ts +1 -0
  32. package/impl/encoded-types/array-proxy.d.ts +1 -0
  33. package/impl/encoded-types/constants.d.ts +1 -0
  34. package/impl/encoded-types/encoded-types.d.ts +1 -0
  35. package/impl/encoded-types/helpers.d.ts +1 -0
  36. package/impl/encoded-types/index.d.ts +1 -0
  37. package/impl/encoded-types/types.d.ts +1 -0
  38. package/impl/encoded-types/utils.d.ts +1 -0
  39. package/impl/ensure-budget.d.ts +1 -0
  40. package/impl/global.d.ts +8 -6
  41. package/impl/gtxn.d.ts +1 -2
  42. package/impl/index.d.ts +1 -15
  43. package/impl/inner-transactions.d.ts +17 -32
  44. package/impl/itxn-compose.d.ts +1 -0
  45. package/impl/itxn.d.ts +2 -8
  46. package/impl/log.d.ts +1 -0
  47. package/impl/logicSigArg.d.ts +1 -0
  48. package/impl/match.d.ts +1 -0
  49. package/impl/method-selector.d.ts +1 -0
  50. package/impl/online-stake.d.ts +1 -0
  51. package/impl/primitives.d.ts +76 -0
  52. package/impl/pure.d.ts +0 -31
  53. package/impl/reference.d.ts +28 -0
  54. package/impl/scratch.d.ts +1 -4
  55. package/impl/state.d.ts +2 -84
  56. package/impl/template-var.d.ts +1 -0
  57. package/impl/transactions.d.ts +51 -73
  58. package/impl/txn.d.ts +1 -3
  59. package/impl/urange.d.ts +1 -0
  60. package/impl/validate-encoding.d.ts +1 -0
  61. package/impl/voter-params.d.ts +5 -0
  62. package/index.d.ts +4 -0
  63. package/index.mjs +1222 -4030
  64. package/index.mjs.map +1 -1
  65. package/inner-transactions-Bc7BmlmL.js +1208 -0
  66. package/inner-transactions-Bc7BmlmL.js.map +1 -0
  67. package/internal/arc4.d.ts +1 -0
  68. package/internal/arc4.mjs +17 -0
  69. package/internal/arc4.mjs.map +1 -0
  70. package/internal/index.d.ts +1 -0
  71. package/internal/index.mjs +245 -0
  72. package/internal/index.mjs.map +1 -0
  73. package/internal/op.d.ts +1 -0
  74. package/internal/op.mjs +17 -0
  75. package/internal/op.mjs.map +1 -0
  76. package/op-D8t8WdBG.js +1881 -0
  77. package/op-D8t8WdBG.js.map +1 -0
  78. package/package.json +29 -13
  79. package/program-factory-C9d-FSGp.js +679 -0
  80. package/program-factory-C9d-FSGp.js.map +1 -0
  81. package/pure-CDvQPyw_.js +691 -0
  82. package/pure-CDvQPyw_.js.map +1 -0
  83. package/runtime-helpers-BfpGXQyk.js +460 -0
  84. package/runtime-helpers-BfpGXQyk.js.map +1 -0
  85. package/runtime-helpers.d.ts +1 -10
  86. package/runtime-helpers.mjs +6 -3
  87. package/runtime-helpers.mjs.map +1 -1
  88. package/set-up.d.ts +21 -1
  89. package/subcontexts/contract-context.d.ts +18 -11
  90. package/subcontexts/ledger-context.d.ts +141 -33
  91. package/subcontexts/transaction-context.d.ts +178 -40
  92. package/test-execution-context.d.ts +130 -41
  93. package/test-transformer/errors.d.ts +1 -3
  94. package/test-transformer/helpers.d.ts +1 -2
  95. package/test-transformer/jest-transformer.d.ts +37 -0
  96. package/test-transformer/jest-transformer.mjs +53 -0
  97. package/test-transformer/jest-transformer.mjs.map +1 -0
  98. package/test-transformer/node-factory.d.ts +1 -11
  99. package/test-transformer/program-factory.d.ts +4 -0
  100. package/test-transformer/supported-binary-op-string.d.ts +1 -4
  101. package/test-transformer/visitors.d.ts +1 -11
  102. package/test-transformer/vitest-transformer.d.ts +34 -0
  103. package/test-transformer/vitest-transformer.mjs +57 -0
  104. package/test-transformer/vitest-transformer.mjs.map +1 -0
  105. package/typescript-helpers-sobuICoc.js +70 -0
  106. package/typescript-helpers-sobuICoc.js.map +1 -0
  107. package/typescript-helpers.d.ts +13 -0
  108. package/util.d.ts +33 -28
  109. package/utils-fy0_Fvxl.js +1641 -0
  110. package/utils-fy0_Fvxl.js.map +1 -0
  111. package/value-generators/arc4.d.ts +70 -0
  112. package/value-generators/avm.d.ts +53 -13
  113. package/value-generators/index.d.ts +2 -1
  114. package/value-generators/txn.d.ts +36 -3
  115. package/encoders.d.ts +0 -21
  116. package/impl/account.d.ts +0 -32
  117. package/impl/application.d.ts +0 -30
  118. package/impl/asset.d.ts +0 -24
  119. package/runtime-helpers-C_HAST0y.js +0 -514
  120. package/runtime-helpers-C_HAST0y.js.map +0 -1
  121. package/test-transformer/index.d.ts +0 -6
  122. package/test-transformer/index.mjs +0 -413
  123. package/test-transformer/index.mjs.map +0 -1
package/README.md ADDED
@@ -0,0 +1,307 @@
1
+ # Algorand TypeScript Testing
2
+
3
+ [![docs-repository](https://img.shields.io/badge/url-repository-74dfdc?logo=github&style=flat.svg)](https://github.com/algorandfoundation/algorand-typescript-testing/)
4
+ [![learn-AlgoKit](https://img.shields.io/badge/learn-AlgoKit-74dfdc?logo=algorand&mac=flat.svg)](https://developer.algorand.org/algokit/)
5
+ [![github-stars](https://img.shields.io/github/stars/algorandfoundation/algorand-typescript-testing?color=74dfdc&logo=star&style=flat)](https://github.com/algorandfoundation/algorand-typescript-testing)
6
+ [![visitor-badge](https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fgithub.com%2Falgorandfoundation%2Falgorand-typescript-testing&countColor=%2374dfdc&style=flat)](https://github.com/algorandfoundation/algorand-typescript-testing/)
7
+
8
+ `algorand-typescript-testing` is a companion package to [Algorand Typescript](https://github.com/algorandfoundation/puya-ts/tree/main/packages/algo-ts) that enables efficient unit testing of Algorand TypeScript smart contracts in an offline environment. This package emulates key AVM behaviours without requiring a network connection, offering fast and reliable testing capabilities with a familiar TypeScript interface.
9
+
10
+ The `algorand-typescript-testing` package provides:
11
+
12
+ - A simple interface for fast and reliable unit testing
13
+ - An offline testing environment that simulates core AVM functionality
14
+ - A familiar TypeScript experience, compatible with testing frameworks like [vitest](https://vitest.dev/), and [jest](https://jestjs.io/)
15
+
16
+ ## Quick Start
17
+
18
+ `algorand-typescript` is a prerequisite for `algorand-typescript-testing`, providing stubs and type annotations for Algorand TypeScript syntax. It enhances code completion and type checking when writing smart contracts. Note that this code isn't directly executable in standard Node.js environment; it's compiled by `puya-ts` into TEAL for Algorand Network deployment.
19
+
20
+ Traditionally, testing Algorand smart contracts involved deployment on sandboxed networks and interacting with live instances. While robust, this approach can be inefficient and lacks versatility for testing Algorand TypeScript code.
21
+
22
+ Enter `algorand-typescript-testing`: it leverages TypeScript's rich testing ecosystem for unit testing without network deployment. This enables rapid iteration and granular logic testing.
23
+
24
+ > **NOTE**: While `algorand-typescript-testing` offers valuable unit testing capabilities, it's not a replacement for comprehensive testing. Use it alongside other test types, particularly those running against the actual Algorand Network, for thorough contract validation.
25
+
26
+ ### Prerequisites
27
+
28
+ - Python 3.12 or later
29
+ - [Algorand Python](https://github.com/algorandfoundation/puya)
30
+ - Node.js 20.x or later
31
+ - [Algorand TypeScript](https://github.com/algorandfoundation/puya-ts)
32
+
33
+ ### Installation
34
+
35
+ `algorand-typescript-testing` is distributed via [npm](https://www.npmjs.com/package/@algorandfoundation/algorand-typescript-testing/). Install the package using `npm`:
36
+
37
+ ```bash
38
+ npm i @algorandfoundation/algorand-typescript-testing
39
+ ```
40
+
41
+ ### Testing your first contract
42
+
43
+ Let's write a simple contract and test it using the `algorand-typescript-testing` framework.
44
+
45
+ #### Simulating AVM
46
+
47
+ `algorand-typescript-testing` includes a TypeScript transformer (`puyaTsTransformer`) that ensures contracts (with `.algo.ts` extension) and tests (with `.algo.spec.ts` or `.algo.test.ts` extensions) behave consistently between Node.js and AVM environments.
48
+
49
+ The transformer replicates AVM behaviour, such as integer-only arithmetic where `3 / 2` produces `1`. For code requiring standard Node.js behaviour (e.g., `3 / 2` produces `1.5`), place it in separate `.ts` files and reference them from test files.
50
+
51
+ The transformer also redirects `@algorandfoundation/algorand-typescript` imports to `@algorandfoundation/algorand-typescript-testing/internal` to provide executable implementations of Algorand TypeScript constructs like `Global`, `Box`, `Uint64`, and `clone`.
52
+
53
+ If there are tests which do not need to be executed in the AVM context such as end to end tests, simply use `.test.ts` or `.spec.ts` file extensions without `.algo` part and the transformer would skip them.
54
+
55
+ #### Configuring vitest
56
+
57
+ If you are using [vitest](https://vitest.dev/) with [@rollup/plugin-typescript](https://www.npmjs.com/package/@rollup/plugin-typescript) plugin, configure `puyaTsTransformer` as a `before` stage transformer of the `typescript` plugin in `vitest.config.mts` file.
58
+
59
+ ```typescript
60
+ import typescript from '@rollup/plugin-typescript'
61
+ import { defineConfig } from 'vitest/config'
62
+ import { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer'
63
+
64
+ export default defineConfig({
65
+ esbuild: {},
66
+ test: {
67
+ setupFiles: 'vitest.setup.ts',
68
+ },
69
+ plugins: [
70
+ typescript({
71
+ transformers: {
72
+ before: [puyaTsTransformer],
73
+ },
74
+ }),
75
+ ],
76
+ })
77
+ ```
78
+
79
+ `algorand-typescript-testing` package also exposes additional equality testers which enables the smart contract developers to write terser test by avoiding type casting in assertions. It can setup in `beforeAll` hook point in the setup file, `vitest.setup.ts`.
80
+
81
+ ```typescript
82
+ import { beforeAll, expect } from 'vitest'
83
+ import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'
84
+
85
+ beforeAll(() => {
86
+ addEqualityTesters({ expect })
87
+ })
88
+ ```
89
+
90
+ #### Configuring jest
91
+
92
+ If you are using [jest](https://jestjs.io/) with [ts-jest](https://www.npmjs.com/package/ts-jest), [@jest/globals](https://www.npmjs.com/package/@jest/globals) and [ts-node](https://www.npmjs.com/package/ts-node) plugins, configure `puyaTsTransformer` as a `before` stage transformer of the `typescript` plugin in `jest.config.ts` file.
93
+
94
+ ```typescript
95
+ import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest'
96
+
97
+ const presetConfig = createDefaultEsmPreset({})
98
+ const jestConfig: JestConfigWithTsJest = {
99
+ ...presetConfig,
100
+ testMatch: ['**/*.algo.test.ts'],
101
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
102
+ transform: {
103
+ '^.+\\.tsx?$': [
104
+ 'ts-jest',
105
+ {
106
+ useESM: true,
107
+ astTransformers: {
108
+ before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'],
109
+ },
110
+ },
111
+ ],
112
+ },
113
+ extensionsToTreatAsEsm: ['.ts'],
114
+ }
115
+ export default jestConfig
116
+ ```
117
+
118
+ `algorand-typescript-testing` package also exposes additional equality testers which enables the smart contract developers to write terser test by avoiding type casting in assertions. It can setup in `beforeAll` hook point in the setup file, `jest.setup.ts`.
119
+
120
+ ```typescript
121
+ import { beforeAll, expect } from '@jest/globals'
122
+ import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'
123
+
124
+ beforeAll(() => {
125
+ addEqualityTesters({ expect })
126
+ })
127
+ ```
128
+
129
+ You'll also need to run `jest` with the `--experimental-vm-modules` and `--experimental-require-module` flags in the `package.json`. This requires node 20.17 or greater.
130
+
131
+ ```json
132
+ {
133
+ "name": "puya-ts-demo",
134
+ "scripts": {
135
+ "test:jest": "tsc && node --experimental-vm-modules --experimental-require-module node_modules/jest/bin/jest"
136
+ },
137
+ "engines": {
138
+ "node": ">=20.17"
139
+ }
140
+ }
141
+ ```
142
+
143
+ There is also a patch file `ts-jest+29.2.5.patch` that needs to be applied to `ts-jest` package to for the `puyaTsTransformer` to work with the test files.
144
+
145
+ 1. Place the file in `<rootDir>\patches` folder.
146
+ 1. Install [patch-package](https://www.npmjs.com/package/patch-package) package as a dev dependency.
147
+ 1. Add `"postinstall": "patch-package",` script in `package.json` file.
148
+ The patch will then be applied with every `npm install` call.
149
+
150
+ ```patch
151
+ diff --git a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js
152
+ index 5198f8f..addb47c 100644
153
+ --- a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js
154
+ +++ b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js
155
+ @@ -234,7 +234,7 @@ var TsCompiler = /** @class */ (function () {
156
+ var _a;
157
+ // Initialize memory cache for typescript compiler
158
+ this._parsedTsConfig.fileNames
159
+ - .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName) && !_this.configSet.isTestFile(fileName); })
160
+ + .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName); })
161
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
162
+ .forEach(function (fileName) { return _this._fileVersionCache.set(fileName, 0); });
163
+ /* istanbul ignore next */
164
+
165
+ ```
166
+
167
+ After the setup, the examples provided using `vitest` can be converted to work with `jest` by simply swapping the `import {...} from 'vitest'` with `import {...} from '@jest/globals'`.
168
+
169
+ #### Contract Definition
170
+
171
+ ```typescript
172
+ import {
173
+ arc4,
174
+ assert,
175
+ Bytes,
176
+ GlobalState,
177
+ gtxn,
178
+ LocalState,
179
+ op,
180
+ readonly,
181
+ Txn,
182
+ uint64,
183
+ Uint64,
184
+ } from '@algorandfoundation/algorand-typescript'
185
+
186
+ export default class VotingContract extends arc4.Contract {
187
+ topic = GlobalState({ initialValue: 'default_topic', key: Bytes('topic') })
188
+ votes = GlobalState({ initialValue: Uint64(0), key: Bytes('votes') })
189
+ voted = LocalState<uint64>({ key: Bytes('voted') })
190
+
191
+ @arc4.abimethod()
192
+ public setTopic(topic: string): void {
193
+ this.topic.value = topic
194
+ }
195
+ @arc4.abimethod()
196
+ public vote(pay: gtxn.PaymentTxn): boolean {
197
+ assert(op.Global.groupSize === 2, 'Expected 2 transactions')
198
+ assert(pay.amount === 10_000, 'Incorrect payment amount')
199
+ assert(pay.sender === Txn.sender, 'Payment sender must match transaction sender')
200
+
201
+ if (this.voted(Txn.sender).hasValue) {
202
+ return false // Already voted
203
+ }
204
+
205
+ this.votes.value = this.votes.value + 1
206
+ this.voted(Txn.sender).value = 1
207
+ return true
208
+ }
209
+
210
+ @readonly
211
+ public getVotes(): uint64 {
212
+ return this.votes.value
213
+ }
214
+
215
+ public clearStateProgram(): boolean {
216
+ return true
217
+ }
218
+ }
219
+ ```
220
+
221
+ #### Test Definition
222
+
223
+ ```typescript
224
+ import { Uint64 } from '@algorandfoundation/algorand-typescript'
225
+ import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing'
226
+ import { afterEach, describe, expect, test } from 'vitest'
227
+ import VotingContract from './contract.algo'
228
+
229
+ describe('Voting contract', () => {
230
+ const ctx = new TestExecutionContext()
231
+ afterEach(() => {
232
+ ctx.reset()
233
+ })
234
+
235
+ test('vote function', () => {
236
+ // Initialize the contract within the testing context
237
+ const contract = ctx.contract.create(VotingContract)
238
+
239
+ const voter = ctx.defaultSender
240
+ const payment = ctx.any.txn.payment({
241
+ sender: voter,
242
+ amount: 10_000,
243
+ })
244
+
245
+ const result = contract.vote(payment)
246
+ expect(result).toEqual(true)
247
+ expect(contract.votes.value).toEqual(1)
248
+ expect(contract.voted(voter).value).toEqual(1)
249
+ })
250
+
251
+ test('setTopic function', () => {
252
+ // Initialize the contract within the testing context
253
+ const contract = ctx.contract.create(VotingContract)
254
+
255
+ const newTopic = ctx.any.string(10)
256
+ contract.setTopic(newTopic)
257
+ expect(contract.topic.value).toEqual(newTopic)
258
+ })
259
+
260
+ test('getVotes function', () => {
261
+ // Initialize the contract within the testing context
262
+ const contract = ctx.contract.create(VotingContract)
263
+
264
+ contract.votes.value = 5
265
+ const votes = contract.getVotes()
266
+ expect(votes).toEqual(5)
267
+ })
268
+ })
269
+ ```
270
+
271
+ This example demonstrates key aspects of testing with `algorand-typescript-testing` for ARC4-based contracts:
272
+
273
+ 1. ARC4 Contract Features:
274
+
275
+ - Use of `arc4.Contract` as the base class for the contract.
276
+ - ABI methods defined using the `@arc4.abimethod` decorator.
277
+ - Readonly method annotation with `@arc4.abimethod({readonly: true})` or `@readonly`.
278
+
279
+ 2. Testing ARC4 Contracts:
280
+
281
+ - Creation of an `arc4.Contract` instance within the test context.
282
+ - Use of `ctx.any` for generating random test data.
283
+ - Direct invocation of ABI methods on the contract instance.
284
+
285
+ 3. Transaction Handling:
286
+
287
+ - Use of `ctx.any.txn` to create test transactions.
288
+ - Passing transaction objects as parameters to contract methods.
289
+
290
+ 4. State Verification:
291
+ - Checking global and local state changes after method execution.
292
+ - Verifying return values from ABI methods.
293
+
294
+ > **NOTE**: Thorough testing is crucial in smart contract development due to their immutable nature post-deployment. Comprehensive unit and integration tests ensure contract validity and reliability. Optimizing for efficiency can significantly improve user experience by reducing transaction fees and simplifying interactions. Investing in robust testing and optimization practices is crucial and offers many benefits in the long run.
295
+
296
+ ### Next steps
297
+
298
+ To dig deeper into the capabilities of `algorand-typescript-testing`, continue with the following sections.
299
+
300
+ #### Contents
301
+
302
+ - [Testing Guide](https://algorandfoundation.github.io/algorand-typescript-testing/documents/Algorand_TypeScript_Testing_Guide.html)
303
+ - [Examples](https://algorandfoundation.github.io/algorand-typescript-testing/documents/Examples.html)
304
+ - [Coverage](https://algorandfoundation.github.io/algorand-typescript-testing/documents/Coverage.html)
305
+ - [FAQ](https://algorandfoundation.github.io/algorand-typescript-testing/documents/FAQ.html)
306
+ - [API Reference](https://algorandfoundation.github.io/algorand-typescript-testing/documents/API_Reference.html)
307
+ - [Algorand TypeScript](https://algorandfoundation.github.io/algorand-typescript-testing/documents/Algorand_TypeScript.html)
package/abi-metadata.d.ts CHANGED
@@ -1,16 +1,4 @@
1
- import { BaseContract, Contract } from '@algorandfoundation/algorand-typescript';
2
- import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript/arc4';
3
- export interface AbiMetadata {
4
- methodName: string;
5
- methodSelector: string;
6
- argTypes: string[];
7
- returnType: string;
8
- onCreate?: CreateOptions;
9
- allowActions?: OnCompleteActionStr[];
10
- }
11
- export declare const attachAbiMetadata: (contract: {
1
+ import { Contract } from './impl/contract';
2
+ export declare const getContractByName: (contractFullname: string) => {
12
3
  new (): Contract;
13
- }, methodName: string, metadata: AbiMetadata) => void;
14
- export declare const captureMethodConfig: <T extends Contract>(contract: T, methodName: string, config?: AbiMethodConfig<T> | BareMethodConfig) => void;
15
- export declare const hasAbiMetadata: <T extends Contract>(contract: T) => boolean;
16
- export declare const getAbiMetadata: <T extends BaseContract>(contract: T, methodName: string) => AbiMetadata;
4
+ } | undefined;
@@ -0,0 +1,32 @@
1
+ import type { bytes, Contract } from '@algorandfoundation/algorand-typescript';
2
+ import { OnCompleteAction } from '@algorandfoundation/algorand-typescript';
3
+ import type { ApplicationCallInnerTxnContext } from './impl/inner-transactions';
4
+ import type { AnyFunction, ConstructorFor } from './typescript-helpers';
5
+ export type AppSpyCb = (itxnContext: ApplicationCallInnerTxnContext) => void;
6
+ export declare class ApplicationSpy<TContract extends Contract = Contract> {
7
+ #private;
8
+ /**
9
+ * The `on` property is a proxy that allows you to register callbacks for specific method signatures.
10
+ * It dynamically creates methods based on the contract's methods.
11
+ */
12
+ readonly on: TypedApplicationSpyCallBacks<TContract>;
13
+ constructor(contract?: TContract | ConstructorFor<TContract>);
14
+ /**
15
+ * Registers a callback for a bare call (no arguments).
16
+ * @param callback - The callback to be executed when a bare call is detected.
17
+ */
18
+ onBareCall(callback: AppSpyCb): void;
19
+ onBareCall(ocas: OnCompleteAction[], callback: AppSpyCb): void;
20
+ /**
21
+ * Registers a callback for a specific method signature.
22
+ * @param methodSignature
23
+ * @param callback
24
+ */
25
+ onAbiCall(methodSignature: bytes, callback: AppSpyCb): void;
26
+ onAbiCall(methodSignature: bytes, ocas: OnCompleteAction[], callback: AppSpyCb): void;
27
+ private _tryGetMethod;
28
+ private createOnProxy;
29
+ }
30
+ export type TypedApplicationSpyCallBacks<TContract> = {
31
+ [key in keyof TContract as key extends 'approvalProgram' | 'clearStateProgram' ? never : TContract[key] extends AnyFunction ? key extends string ? key : never : never]: (callback: AppSpyCb) => void;
32
+ };
@@ -0,0 +1,143 @@
1
+ import * as arc4$1 from '@algorandfoundation/algorand-typescript/arc4';
2
+ import { OnCompleteAction } from '@algorandfoundation/algorand-typescript';
3
+ import { d as getContractByName, g as getContractMethodAbiMetadata, C as Contract, b as abimethod, c as baremethod, r as readonly } from './runtime-helpers-BfpGXQyk.js';
4
+ import { v as lazyContext, a0 as sizeOf } from './utils-fy0_Fvxl.js';
5
+ import { I as InternalError } from './typescript-helpers-sobuICoc.js';
6
+ import { A as ApplicationCallInnerTxnContext, m as methodSelector } from './inner-transactions-Bc7BmlmL.js';
7
+ import { A as Address, B as Bool, c as Byte, d as DynamicArray, D as DynamicBytes, F as FixedArray, R as ReferenceArray, e as StaticArray, f as StaticBytes, S as Str, h as Struct, T as Tuple, i as UFixed, U as Uint, j as convertBytes, k as decodeArc4, l as encodeArc4 } from './asset-params-BwXtTjOo.js';
8
+
9
+ function _mergeNamespaces(n, m) {
10
+ m.forEach(function (e) {
11
+ e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default' && !(k in n)) {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ });
21
+ return Object.freeze(n);
22
+ }
23
+
24
+ /** @internal */
25
+ function compileArc4(contract, options) {
26
+ let app;
27
+ const compiledAppEntry = lazyContext.value.getCompiledAppEntry(contract);
28
+ if (compiledAppEntry !== undefined) {
29
+ app = lazyContext.ledger.applicationDataMap.get(compiledAppEntry.value);
30
+ }
31
+ if (options?.templateVars) {
32
+ Object.entries(options.templateVars).forEach(([key, value]) => {
33
+ lazyContext.value.setTemplateVar(key, value, options.templateVarsPrefix);
34
+ });
35
+ }
36
+ return {
37
+ call: new Proxy({}, {
38
+ get: (_target, prop) => {
39
+ return (methodArgs) => {
40
+ const selector = methodSelector(prop, contract);
41
+ const abiMetadata = getContractMethodAbiMetadata(contract, prop);
42
+ const onCompleteActions = abiMetadata?.allowActions?.map((action) => OnCompleteAction[action]);
43
+ const itxnContext = ApplicationCallInnerTxnContext.createFromTypedApplicationCallFields({
44
+ ...getCommonApplicationCallFields(app, options),
45
+ onCompletion: onCompleteActions?.[0],
46
+ ...methodArgs,
47
+ }, selector, abiMetadata?.resourceEncoding);
48
+ invokeAbiCall(itxnContext);
49
+ return {
50
+ itxn: itxnContext,
51
+ returnValue: itxnContext.loggedReturnValue,
52
+ };
53
+ };
54
+ },
55
+ }),
56
+ bareCreate: (methodArgs) => {
57
+ const itxnContext = ApplicationCallInnerTxnContext.createFromBareCreateApplicationCallFields({
58
+ ...getCommonApplicationCallFields(app, options),
59
+ ...methodArgs,
60
+ });
61
+ invokeAbiCall(itxnContext);
62
+ return itxnContext;
63
+ },
64
+ approvalProgram: app?.application.approvalProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],
65
+ clearStateProgram: app?.application.clearStateProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],
66
+ extraProgramPages: options?.extraProgramPages ?? app?.application.extraProgramPages ?? lazyContext.any.uint64(),
67
+ globalUints: options?.globalUints ?? app?.application.globalNumUint ?? lazyContext.any.uint64(),
68
+ globalBytes: options?.globalBytes ?? app?.application.globalNumBytes ?? lazyContext.any.uint64(),
69
+ localUints: options?.localUints ?? app?.application.localNumUint ?? lazyContext.any.uint64(),
70
+ localBytes: options?.localBytes ?? app?.application.localNumBytes ?? lazyContext.any.uint64(),
71
+ };
72
+ }
73
+ /** @internal */
74
+ const invokeAbiCall = (itxnContext) => {
75
+ lazyContext.value.notifyApplicationSpies(itxnContext);
76
+ lazyContext.txn.activeGroup.addInnerTransactionGroup(...(itxnContext.itxns ?? []), itxnContext);
77
+ };
78
+ const getCommonApplicationCallFields = (app, options) => ({
79
+ approvalProgram: app?.application.approvalProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],
80
+ clearStateProgram: app?.application.clearStateProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],
81
+ extraProgramPages: options?.extraProgramPages ?? app?.application.extraProgramPages ?? lazyContext.any.uint64(),
82
+ globalNumUint: options?.globalUints ?? app?.application.globalNumUint ?? lazyContext.any.uint64(),
83
+ globalNumBytes: options?.globalBytes ?? app?.application.globalNumBytes ?? lazyContext.any.uint64(),
84
+ localNumUint: options?.localUints ?? app?.application.localNumUint ?? lazyContext.any.uint64(),
85
+ localNumBytes: options?.localBytes ?? app?.application.localNumBytes ?? lazyContext.any.uint64(),
86
+ });
87
+ /** @internal */
88
+ function getApplicationCallInnerTxnContext(method, methodArgs, contract) {
89
+ const abiMetadata = contract ? getContractMethodAbiMetadata(contract, method.name) : undefined;
90
+ const selector = methodSelector(method, contract);
91
+ return ApplicationCallInnerTxnContext.createFromTypedApplicationCallFields({
92
+ ...methodArgs,
93
+ onCompletion: methodArgs.onCompletion ?? abiMetadata?.allowActions?.map((action) => OnCompleteAction[action])[0],
94
+ }, selector, abiMetadata?.resourceEncoding);
95
+ }
96
+ /** @internal */
97
+ function abiCall(contractFullName, method, methodArgs) {
98
+ const contract = getContractByName(contractFullName);
99
+ if (contract === undefined || typeof contract !== 'function')
100
+ throw new InternalError(`Unknown contract: ${contractFullName}`);
101
+ if (!Object.hasOwn(contract.prototype, method))
102
+ throw new InternalError(`Unknown method: ${method} in contract: ${contractFullName}`);
103
+ const itxnContext = getApplicationCallInnerTxnContext(contract.prototype[method], methodArgs, contract);
104
+ invokeAbiCall(itxnContext);
105
+ return {
106
+ itxn: itxnContext,
107
+ returnValue: itxnContext.loggedReturnValue,
108
+ };
109
+ }
110
+
111
+ /** @internal */
112
+
113
+ var arc4 = /*#__PURE__*/_mergeNamespaces({
114
+ __proto__: null,
115
+ Address: Address,
116
+ Bool: Bool,
117
+ Byte: Byte,
118
+ Contract: Contract,
119
+ DynamicArray: DynamicArray,
120
+ DynamicBytes: DynamicBytes,
121
+ FixedArray: FixedArray,
122
+ ReferenceArray: ReferenceArray,
123
+ StaticArray: StaticArray,
124
+ StaticBytes: StaticBytes,
125
+ Str: Str,
126
+ Struct: Struct,
127
+ Tuple: Tuple,
128
+ UFixed: UFixed,
129
+ Uint: Uint,
130
+ abiCall: abiCall,
131
+ abimethod: abimethod,
132
+ baremethod: baremethod,
133
+ compileArc4: compileArc4,
134
+ convertBytes: convertBytes,
135
+ decodeArc4: decodeArc4,
136
+ encodeArc4: encodeArc4,
137
+ methodSelector: methodSelector,
138
+ readonly: readonly,
139
+ sizeOf: sizeOf
140
+ }, [arc4$1]);
141
+
142
+ export { arc4 as a, abiCall as b, compileArc4 as c, getApplicationCallInnerTxnContext as g };
143
+ //# sourceMappingURL=arc4-DZBwKOPQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arc4-DZBwKOPQ.js","sources":["../src/impl/c2c.ts","../src/internal/arc4.ts"],"sourcesContent":["import { type CompileContractOptions, type Contract, OnCompleteAction } from '@algorandfoundation/algorand-typescript'\nimport type {\n BareCreateApplicationCallFields,\n ContractProxy,\n TypedApplicationCallFields,\n} from '@algorandfoundation/algorand-typescript/arc4'\nimport { getContractByName, getContractMethodAbiMetadata } from '../abi-metadata'\nimport { lazyContext } from '../context-helpers/internal-context'\nimport { InternalError } from '../errors'\nimport type { ConstructorFor, DeliberateAny, InstanceMethod } from '../typescript-helpers'\nimport type { ApplicationCallInnerTxn } from './inner-transactions'\nimport { ApplicationCallInnerTxnContext } from './inner-transactions'\nimport { methodSelector } from './method-selector'\nimport type { ApplicationData } from './reference'\n\n/** @internal */\nexport function compileArc4<TContract extends Contract>(\n contract: ConstructorFor<TContract>,\n options?: CompileContractOptions,\n): ContractProxy<TContract> {\n let app: ApplicationData | undefined\n const compiledAppEntry = lazyContext.value.getCompiledAppEntry(contract)\n if (compiledAppEntry !== undefined) {\n app = lazyContext.ledger.applicationDataMap.get(compiledAppEntry.value)\n }\n\n if (options?.templateVars) {\n Object.entries(options.templateVars).forEach(([key, value]) => {\n lazyContext.value.setTemplateVar(key, value, options.templateVarsPrefix)\n })\n }\n\n return {\n call: new Proxy({} as unknown as TContract, {\n get: (_target, prop) => {\n return (methodArgs: TypedApplicationCallFields<DeliberateAny[]>) => {\n const selector = methodSelector(prop as string, contract)\n const abiMetadata = getContractMethodAbiMetadata(contract, prop as string)\n const onCompleteActions = abiMetadata?.allowActions?.map((action) => OnCompleteAction[action])\n const itxnContext = ApplicationCallInnerTxnContext.createFromTypedApplicationCallFields(\n {\n ...getCommonApplicationCallFields(app, options),\n onCompletion: onCompleteActions?.[0],\n ...methodArgs,\n },\n selector,\n abiMetadata?.resourceEncoding,\n )\n invokeAbiCall(itxnContext)\n return {\n itxn: itxnContext,\n returnValue: itxnContext.loggedReturnValue,\n }\n }\n },\n }),\n\n bareCreate: (methodArgs?: BareCreateApplicationCallFields) => {\n const itxnContext = ApplicationCallInnerTxnContext.createFromBareCreateApplicationCallFields({\n ...getCommonApplicationCallFields(app, options),\n ...methodArgs,\n })\n invokeAbiCall(itxnContext)\n return itxnContext\n },\n approvalProgram: app?.application.approvalProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],\n clearStateProgram: app?.application.clearStateProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],\n extraProgramPages: options?.extraProgramPages ?? app?.application.extraProgramPages ?? lazyContext.any.uint64(),\n globalUints: options?.globalUints ?? app?.application.globalNumUint ?? lazyContext.any.uint64(),\n globalBytes: options?.globalBytes ?? app?.application.globalNumBytes ?? lazyContext.any.uint64(),\n localUints: options?.localUints ?? app?.application.localNumUint ?? lazyContext.any.uint64(),\n localBytes: options?.localBytes ?? app?.application.localNumBytes ?? lazyContext.any.uint64(),\n } as unknown as ContractProxy<TContract>\n}\n\n/** @internal */\nexport const invokeAbiCall = (itxnContext: ApplicationCallInnerTxnContext) => {\n lazyContext.value.notifyApplicationSpies(itxnContext)\n lazyContext.txn.activeGroup.addInnerTransactionGroup(...(itxnContext.itxns ?? []), itxnContext)\n}\nconst getCommonApplicationCallFields = (app: ApplicationData | undefined, options: CompileContractOptions | undefined) => ({\n approvalProgram: app?.application.approvalProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],\n clearStateProgram: app?.application.clearStateProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)],\n extraProgramPages: options?.extraProgramPages ?? app?.application.extraProgramPages ?? lazyContext.any.uint64(),\n globalNumUint: options?.globalUints ?? app?.application.globalNumUint ?? lazyContext.any.uint64(),\n globalNumBytes: options?.globalBytes ?? app?.application.globalNumBytes ?? lazyContext.any.uint64(),\n localNumUint: options?.localUints ?? app?.application.localNumUint ?? lazyContext.any.uint64(),\n localNumBytes: options?.localBytes ?? app?.application.localNumBytes ?? lazyContext.any.uint64(),\n})\n\n/** @internal */\nexport function getApplicationCallInnerTxnContext<TArgs extends DeliberateAny[], TReturn = void>(\n method: InstanceMethod<Contract, TArgs, TReturn>,\n methodArgs: TypedApplicationCallFields<TArgs>,\n contract?: Contract | { new (): Contract },\n) {\n const abiMetadata = contract ? getContractMethodAbiMetadata(contract, method.name) : undefined\n const selector = methodSelector(method, contract)\n return ApplicationCallInnerTxnContext.createFromTypedApplicationCallFields<TReturn>(\n {\n ...methodArgs,\n onCompletion: methodArgs.onCompletion ?? abiMetadata?.allowActions?.map((action) => OnCompleteAction[action])[0],\n },\n selector,\n abiMetadata?.resourceEncoding,\n )\n}\n/** @internal */\nexport function abiCall<TArgs extends DeliberateAny[], TReturn>(\n contractFullName: string,\n method: string,\n methodArgs: TypedApplicationCallFields<TArgs>,\n): { itxn: ApplicationCallInnerTxn; returnValue: TReturn | undefined } {\n const contract = getContractByName(contractFullName)\n if (contract === undefined || typeof contract !== 'function') throw new InternalError(`Unknown contract: ${contractFullName}`)\n if (!Object.hasOwn(contract.prototype, method)) throw new InternalError(`Unknown method: ${method} in contract: ${contractFullName}`)\n\n const itxnContext = getApplicationCallInnerTxnContext<TArgs, TReturn>(contract.prototype[method], methodArgs, contract)\n\n invokeAbiCall(itxnContext)\n\n return {\n itxn: itxnContext,\n returnValue: itxnContext.loggedReturnValue,\n }\n}\n","/** @internal */\nexport * from '@algorandfoundation/algorand-typescript/arc4'\n/** @internal */\nexport { abiCall, compileArc4 } from '../impl/c2c'\n/** @internal */\nexport { abimethod, baremethod, Contract, readonly } from '../impl/contract'\n/** @internal */\nexport {\n Address,\n Bool,\n Byte,\n convertBytes,\n decodeArc4,\n DynamicArray,\n DynamicBytes,\n encodeArc4,\n FixedArray,\n ReferenceArray,\n sizeOf,\n StaticArray,\n StaticBytes,\n Str,\n Struct,\n Tuple,\n UFixed,\n Uint,\n} from '../impl/encoded-types'\n/** @internal */\nexport { methodSelector } from '../impl/method-selector'\n"],"names":[],"mappings":"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"}