diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml new file mode 100644 index 0000000..895b0c9 --- /dev/null +++ b/.github/workflows/gh-pages.yml @@ -0,0 +1,35 @@ +name: 'Run typedoc and publish to pages' + +on: + push: + branches: + - main +jobs: + build-and-publish-docs: + runs-on: ubuntu-latest + permissions: + contents: read + pages: write + id-token: write + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Use Node.js 21.x + uses: actions/setup-node@v4 + with: + node-version: 21.x + + - name: Npm install + run: npm ci --ignore-scripts + + - name: Build doc + run: npm run script:documentation + + - name: Upload to GitHub pages + uses: actions/upload-pages-artifact@v3 + with: + path: docs/_html + + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 119c7fb..4b40876 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ test-results.xml # Website & Code docs generation code-docs/ out/ +docs/_html # dotenv environment variable files .env diff --git a/README.md b/README.md index 47f169c..1620f2b 100644 --- a/README.md +++ b/README.md @@ -287,7 +287,7 @@ To dig deeper into the capabilities of `algorand-typescript-testing`, continue w #### Contents -- [Testing Guide](./docs/testing-guide/index.md) +- [Testing Guide](./docs/testing-guide.md) - [Examples](./docs/examples.md) - [Coverage](./docs/coverage.md) - [FQA](./docs/faq.md) diff --git a/docs/algots.md b/docs/algots.md index 7efd44f..440ec23 100644 --- a/docs/algots.md +++ b/docs/algots.md @@ -1,3 +1,7 @@ +--- +title: Algorand TypeScript +--- + # Algorand TypeScript Algorand TypeScript is a partial implementation of the TypeScript programming language that runs on the Algorand Virtual Machine (AVM). It includes a statically typed framework for development of Algorand smart contracts and logic signatures, with TypeScript interfaces to underlying AVM functionality that works with standard TypeScript tooling. @@ -8,4 +12,4 @@ and debugged on a Node.js virtual machine with transpilation to EcmaScript and r Algorand TypeScript is compiled for execution on the AVM by PuyaTs, a TypeScript frontend for the [Puya](https://github.com/algorandfoundation/puya) optimising compiler that ensures the resulting AVM bytecode execution semantics that match the given TypeScript code. PuyaTs produces output that is directly compatible with AlgoKit typed clients to make deployment and calling easy. -[Documentation](https://github.com/algorandfoundation/puya-ts/blob/main/README.md) +[Documentation](https://algorandfoundation.github.io/puya-ts/index.html) diff --git a/docs/api.md b/docs/api.md index c6ea0a7..dda092b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,29 +1,33 @@ +--- +title: API Reference +--- + # API Reference An overview of the `algorand-typescript-testing` package - covering the main classes and functions. -```{hint} +``` Spotted a typo in documentation? This project is open source, please submit an issue or a PR on [GitHub](https://github.com/algorandfoundation/algorand-typescript-testing). ``` ## Contexts -- [TestExecutionContext](./code/index/classes/TestExecutionContext.md) -- [ContractContext](./code/subcontexts/contract-context/classes/ContractContext.md) -- [LedgerContext](./code/subcontexts/ledger-context/classes/LedgerContext.md) -- [TransactionContext](./code/subcontexts/transaction-context/classes/TransactionContext.md) +- [TestExecutionContext](../classes/index.TestExecutionContext.html) +- [ContractContext](../classes/index._internal_.ContractContext.html) +- [LedgerContext](../classes/index._internal_.LedgerContext.html) +- [TransactionContext](../classes/index._internal_.TransactionContext.html) ## Value Generators -- [AvmValueGenerator](./code/value-generators/avm/classes/AvmValueGenerator.md) -- [Arc4ValueGenerator](./code/value-generators/arc4/classes/Arc4ValueGenerator.md) -- [TxnValueGenerator](./code/value-generators/txn/classes/TxnValueGenerator.md) +- [AvmValueGenerator](../classes/value-generators._internal_.AvmValueGenerator.html) +- [Arc4ValueGenerator](../classes/value-generators._internal_.Arc4ValueGenerator.html) +- [TxnValueGenerator](../classes/value-generators._internal_.TxnValueGenerator.html) ## Utils -- [addEqualityTesters](./code/index/functions/addEqualityTesters.md) -- [encodingUtils](./code/index/variables/encodingUtil.md) +- [addEqualityTesters](../functions/index.addEqualityTesters.html) +- [toExternalValue](../functions/index.toExternalValue.html) ## Reference documentation -We also have [auto-generated reference documentation for the code](./code/README.md). +We also have [auto-generated reference documentation for the code](../modules/index.html). diff --git a/docs/code/README.md b/docs/code/README.md deleted file mode 100644 index a729f30..0000000 --- a/docs/code/README.md +++ /dev/null @@ -1,18 +0,0 @@ -**@algorandfoundation/algorand-typescript-testing** - -*** - -# @algorandfoundation/algorand-typescript-testing - -## Modules - -- [index](index/README.md) -- [subcontexts/contract-context](subcontexts/contract-context/README.md) -- [subcontexts/ledger-context](subcontexts/ledger-context/README.md) -- [subcontexts/transaction-context](subcontexts/transaction-context/README.md) -- [test-transformer/jest-transformer](test-transformer/jest-transformer/README.md) -- [test-transformer/vitest-transformer](test-transformer/vitest-transformer/README.md) -- [value-generators](value-generators/README.md) -- [value-generators/arc4](value-generators/arc4/README.md) -- [value-generators/avm](value-generators/avm/README.md) -- [value-generators/txn](value-generators/txn/README.md) diff --git a/docs/code/index/README.md b/docs/code/index/README.md deleted file mode 100644 index 9934544..0000000 --- a/docs/code/index/README.md +++ /dev/null @@ -1,22 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../README.md) / index - -# index - -## Classes - -- [ApplicationSpy](classes/ApplicationSpy.md) -- [AssertError](classes/AssertError.md) -- [AvmError](classes/AvmError.md) -- [CodeError](classes/CodeError.md) -- [InternalError](classes/InternalError.md) -- [NotImplementedError](classes/NotImplementedError.md) -- [TestExecutionContext](classes/TestExecutionContext.md) - -## Functions - -- [addEqualityTesters](functions/addEqualityTesters.md) -- [toExternalValue](functions/toExternalValue.md) diff --git a/docs/code/index/classes/ApplicationSpy.md b/docs/code/index/classes/ApplicationSpy.md deleted file mode 100644 index 7504b17..0000000 --- a/docs/code/index/classes/ApplicationSpy.md +++ /dev/null @@ -1,170 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / ApplicationSpy - -# Class: ApplicationSpy\ - -Defined in: [src/application-spy.ts:34](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L34) - -## Type Parameters - -### TContract - -`TContract` *extends* `Contract` = `Contract` - -## Constructors - -### Constructor - -> **new ApplicationSpy**\<`TContract`\>(`contract`?): `ApplicationSpy`\<`TContract`\> - -Defined in: [src/application-spy.ts:46](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L46) - -#### Parameters - -##### contract? - -`TContract` | `ConstructorFor`\<`TContract`\> - -#### Returns - -`ApplicationSpy`\<`TContract`\> - -## Properties - -### contract? - -> `optional` **contract**: `TContract` \| `ConstructorFor`\<`TContract`\> - -Defined in: [src/application-spy.ts:44](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L44) - -*** - -### on - -> `readonly` **on**: `_TypedApplicationSpyCallBacks`\<`TContract`\> - -Defined in: [src/application-spy.ts:41](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L41) - -The `on` property is a proxy that allows you to register callbacks for specific method signatures. -It dynamically creates methods based on the contract's methods. - -## Methods - -### notify() - -> **notify**(`itxn`): `void` - -Defined in: [src/application-spy.ts:52](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L52) - -#### Parameters - -##### itxn - -`ApplicationCallInnerTxnContext` - -#### Returns - -`void` - -*** - -### onAbiCall() - -#### Call Signature - -> **onAbiCall**(`methodSignature`, `callback`): `void` - -Defined in: [src/application-spy.ts:80](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L80) - -Registers a callback for a specific method signature. - -##### Parameters - -###### methodSignature - -`bytes` - -###### callback - -`AppSpyCb` - -##### Returns - -`void` - -#### Call Signature - -> **onAbiCall**(`methodSignature`, `ocas`, `callback`): `void` - -Defined in: [src/application-spy.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L81) - -Registers a callback for a specific method signature. - -##### Parameters - -###### methodSignature - -`bytes` - -###### ocas - -`OnCompleteAction`[] - -###### callback - -`AppSpyCb` - -##### Returns - -`void` - -*** - -### onBareCall() - -#### Call Signature - -> **onBareCall**(`callback`): `void` - -Defined in: [src/application-spy.ts:62](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L62) - -Registers a callback for a bare call (no arguments). - -##### Parameters - -###### callback - -`AppSpyCb` - -The callback to be executed when a bare call is detected. - -##### Returns - -`void` - -#### Call Signature - -> **onBareCall**(`ocas`, `callback`): `void` - -Defined in: [src/application-spy.ts:63](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/application-spy.ts#L63) - -Registers a callback for a bare call (no arguments). - -##### Parameters - -###### ocas - -`OnCompleteAction`[] - -###### callback - -`AppSpyCb` - -The callback to be executed when a bare call is detected. - -##### Returns - -`void` diff --git a/docs/code/index/classes/AssertError.md b/docs/code/index/classes/AssertError.md deleted file mode 100644 index ce76224..0000000 --- a/docs/code/index/classes/AssertError.md +++ /dev/null @@ -1,157 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / AssertError - -# Class: AssertError - -Defined in: [src/errors.ts:22](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L22) - -Raised when an assertion fails - -## Extends - -- [`AvmError`](AvmError.md) - -## Constructors - -### Constructor - -> **new AssertError**(`message`): `AssertError` - -Defined in: [src/errors.ts:23](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L23) - -#### Parameters - -##### message - -`string` - -#### Returns - -`AssertError` - -#### Overrides - -[`AvmError`](AvmError.md).[`constructor`](AvmError.md#constructor) - -## Properties - -### cause? - -> `optional` **cause**: `unknown` - -Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 - -#### Inherited from - -[`AvmError`](AvmError.md).[`cause`](AvmError.md#cause) - -*** - -### message - -> **message**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 - -#### Inherited from - -[`AvmError`](AvmError.md).[`message`](AvmError.md#message) - -*** - -### name - -> **name**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 - -#### Inherited from - -[`AvmError`](AvmError.md).[`name`](AvmError.md#name) - -*** - -### stack? - -> `optional` **stack**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 - -#### Inherited from - -[`AvmError`](AvmError.md).[`stack`](AvmError.md#stack) - -*** - -### prepareStackTrace()? - -> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` - -Defined in: node\_modules/@types/node/globals.d.ts:143 - -Optional override for formatting stack traces - -#### Parameters - -##### err - -`Error` - -##### stackTraces - -`CallSite`[] - -#### Returns - -`any` - -#### See - -https://v8.dev/docs/stack-trace-api#customizing-stack-traces - -#### Inherited from - -[`AvmError`](AvmError.md).[`prepareStackTrace`](AvmError.md#preparestacktrace) - -*** - -### stackTraceLimit - -> `static` **stackTraceLimit**: `number` - -Defined in: node\_modules/@types/node/globals.d.ts:145 - -#### Inherited from - -[`AvmError`](AvmError.md).[`stackTraceLimit`](AvmError.md#stacktracelimit) - -## Methods - -### captureStackTrace() - -> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` - -Defined in: node\_modules/@types/node/globals.d.ts:136 - -Create .stack property on a target object - -#### Parameters - -##### targetObject - -`object` - -##### constructorOpt? - -`Function` - -#### Returns - -`void` - -#### Inherited from - -[`AvmError`](AvmError.md).[`captureStackTrace`](AvmError.md#capturestacktrace) diff --git a/docs/code/index/classes/AvmError.md b/docs/code/index/classes/AvmError.md deleted file mode 100644 index 6251695..0000000 --- a/docs/code/index/classes/AvmError.md +++ /dev/null @@ -1,162 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / AvmError - -# Class: AvmError - -Defined in: [src/errors.ts:5](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L5) - -Raised when an `err` op is encountered, or when the testing VM is asked to do something that would cause -the AVM to fail. - -## Extends - -- `Error` - -## Extended by - -- [`AssertError`](AssertError.md) - -## Constructors - -### Constructor - -> **new AvmError**(`message`): `AvmError` - -Defined in: [src/errors.ts:6](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L6) - -#### Parameters - -##### message - -`string` - -#### Returns - -`AvmError` - -#### Overrides - -`Error.constructor` - -## Properties - -### cause? - -> `optional` **cause**: `unknown` - -Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 - -#### Inherited from - -`Error.cause` - -*** - -### message - -> **message**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 - -#### Inherited from - -`Error.message` - -*** - -### name - -> **name**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 - -#### Inherited from - -`Error.name` - -*** - -### stack? - -> `optional` **stack**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 - -#### Inherited from - -`Error.stack` - -*** - -### prepareStackTrace()? - -> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` - -Defined in: node\_modules/@types/node/globals.d.ts:143 - -Optional override for formatting stack traces - -#### Parameters - -##### err - -`Error` - -##### stackTraces - -`CallSite`[] - -#### Returns - -`any` - -#### See - -https://v8.dev/docs/stack-trace-api#customizing-stack-traces - -#### Inherited from - -`Error.prepareStackTrace` - -*** - -### stackTraceLimit - -> `static` **stackTraceLimit**: `number` - -Defined in: node\_modules/@types/node/globals.d.ts:145 - -#### Inherited from - -`Error.stackTraceLimit` - -## Methods - -### captureStackTrace() - -> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` - -Defined in: node\_modules/@types/node/globals.d.ts:136 - -Create .stack property on a target object - -#### Parameters - -##### targetObject - -`object` - -##### constructorOpt? - -`Function` - -#### Returns - -`void` - -#### Inherited from - -`Error.captureStackTrace` diff --git a/docs/code/index/classes/CodeError.md b/docs/code/index/classes/CodeError.md deleted file mode 100644 index e93e9d4..0000000 --- a/docs/code/index/classes/CodeError.md +++ /dev/null @@ -1,161 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / CodeError - -# Class: CodeError - -Defined in: [src/errors.ts:40](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L40) - -Raised when unsupported user code is encountered - -## Extends - -- `Error` - -## Constructors - -### Constructor - -> **new CodeError**(`message`, `options`?): `CodeError` - -Defined in: [src/errors.ts:41](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L41) - -#### Parameters - -##### message - -`string` - -##### options? - -`ErrorOptions` - -#### Returns - -`CodeError` - -#### Overrides - -`Error.constructor` - -## Properties - -### cause? - -> `optional` **cause**: `unknown` - -Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 - -#### Inherited from - -`Error.cause` - -*** - -### message - -> **message**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 - -#### Inherited from - -`Error.message` - -*** - -### name - -> **name**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 - -#### Inherited from - -`Error.name` - -*** - -### stack? - -> `optional` **stack**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 - -#### Inherited from - -`Error.stack` - -*** - -### prepareStackTrace()? - -> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` - -Defined in: node\_modules/@types/node/globals.d.ts:143 - -Optional override for formatting stack traces - -#### Parameters - -##### err - -`Error` - -##### stackTraces - -`CallSite`[] - -#### Returns - -`any` - -#### See - -https://v8.dev/docs/stack-trace-api#customizing-stack-traces - -#### Inherited from - -`Error.prepareStackTrace` - -*** - -### stackTraceLimit - -> `static` **stackTraceLimit**: `number` - -Defined in: node\_modules/@types/node/globals.d.ts:145 - -#### Inherited from - -`Error.stackTraceLimit` - -## Methods - -### captureStackTrace() - -> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` - -Defined in: node\_modules/@types/node/globals.d.ts:136 - -Create .stack property on a target object - -#### Parameters - -##### targetObject - -`object` - -##### constructorOpt? - -`Function` - -#### Returns - -`void` - -#### Inherited from - -`Error.captureStackTrace` diff --git a/docs/code/index/classes/InternalError.md b/docs/code/index/classes/InternalError.md deleted file mode 100644 index 1ea9869..0000000 --- a/docs/code/index/classes/InternalError.md +++ /dev/null @@ -1,161 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / InternalError - -# Class: InternalError - -Defined in: [src/errors.ts:31](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L31) - -Raised when testing code errors - -## Extends - -- `Error` - -## Constructors - -### Constructor - -> **new InternalError**(`message`, `options`?): `InternalError` - -Defined in: [src/errors.ts:32](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L32) - -#### Parameters - -##### message - -`string` - -##### options? - -`ErrorOptions` - -#### Returns - -`InternalError` - -#### Overrides - -`Error.constructor` - -## Properties - -### cause? - -> `optional` **cause**: `unknown` - -Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 - -#### Inherited from - -`Error.cause` - -*** - -### message - -> **message**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 - -#### Inherited from - -`Error.message` - -*** - -### name - -> **name**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 - -#### Inherited from - -`Error.name` - -*** - -### stack? - -> `optional` **stack**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 - -#### Inherited from - -`Error.stack` - -*** - -### prepareStackTrace()? - -> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` - -Defined in: node\_modules/@types/node/globals.d.ts:143 - -Optional override for formatting stack traces - -#### Parameters - -##### err - -`Error` - -##### stackTraces - -`CallSite`[] - -#### Returns - -`any` - -#### See - -https://v8.dev/docs/stack-trace-api#customizing-stack-traces - -#### Inherited from - -`Error.prepareStackTrace` - -*** - -### stackTraceLimit - -> `static` **stackTraceLimit**: `number` - -Defined in: node\_modules/@types/node/globals.d.ts:145 - -#### Inherited from - -`Error.stackTraceLimit` - -## Methods - -### captureStackTrace() - -> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` - -Defined in: node\_modules/@types/node/globals.d.ts:136 - -Create .stack property on a target object - -#### Parameters - -##### targetObject - -`object` - -##### constructorOpt? - -`Function` - -#### Returns - -`void` - -#### Inherited from - -`Error.captureStackTrace` diff --git a/docs/code/index/classes/NotImplementedError.md b/docs/code/index/classes/NotImplementedError.md deleted file mode 100644 index ca4788b..0000000 --- a/docs/code/index/classes/NotImplementedError.md +++ /dev/null @@ -1,155 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / NotImplementedError - -# Class: NotImplementedError - -Defined in: [src/errors.ts:46](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L46) - -## Extends - -- `Error` - -## Constructors - -### Constructor - -> **new NotImplementedError**(`feature`): `NotImplementedError` - -Defined in: [src/errors.ts:47](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/errors.ts#L47) - -#### Parameters - -##### feature - -`string` - -#### Returns - -`NotImplementedError` - -#### Overrides - -`Error.constructor` - -## Properties - -### cause? - -> `optional` **cause**: `unknown` - -Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:26 - -#### Inherited from - -`Error.cause` - -*** - -### message - -> **message**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 - -#### Inherited from - -`Error.message` - -*** - -### name - -> **name**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 - -#### Inherited from - -`Error.name` - -*** - -### stack? - -> `optional` **stack**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 - -#### Inherited from - -`Error.stack` - -*** - -### prepareStackTrace()? - -> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` - -Defined in: node\_modules/@types/node/globals.d.ts:143 - -Optional override for formatting stack traces - -#### Parameters - -##### err - -`Error` - -##### stackTraces - -`CallSite`[] - -#### Returns - -`any` - -#### See - -https://v8.dev/docs/stack-trace-api#customizing-stack-traces - -#### Inherited from - -`Error.prepareStackTrace` - -*** - -### stackTraceLimit - -> `static` **stackTraceLimit**: `number` - -Defined in: node\_modules/@types/node/globals.d.ts:145 - -#### Inherited from - -`Error.stackTraceLimit` - -## Methods - -### captureStackTrace() - -> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` - -Defined in: node\_modules/@types/node/globals.d.ts:136 - -Create .stack property on a target object - -#### Parameters - -##### targetObject - -`object` - -##### constructorOpt? - -`Function` - -#### Returns - -`void` - -#### Inherited from - -`Error.captureStackTrace` diff --git a/docs/code/index/classes/TestExecutionContext.md b/docs/code/index/classes/TestExecutionContext.md deleted file mode 100644 index 7a37939..0000000 --- a/docs/code/index/classes/TestExecutionContext.md +++ /dev/null @@ -1,424 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / TestExecutionContext - -# Class: TestExecutionContext - -Defined in: [src/test-execution-context.ts:22](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L22) - -The `TestExecutionContext` class provides a context for executing tests in an Algorand environment. -It manages various contexts such as contract, ledger, and transaction contexts, and provides utilities -for generating values, managing accounts, and handling logic signatures. - -## Constructors - -### Constructor - -> **new TestExecutionContext**(`defaultSenderAddress`?): `TestExecutionContext` - -Defined in: [src/test-execution-context.ts:39](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L39) - -Creates an instance of `TestExecutionContext`. - -#### Parameters - -##### defaultSenderAddress? - -`bytes` - -The default sender address. - -#### Returns - -`TestExecutionContext` - -## Accessors - -### activeLogicSigArgs - -#### Get Signature - -> **get** **activeLogicSigArgs**(): `bytes`[] - -Defined in: [src/test-execution-context.ts:120](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L120) - -Returns the active logic signature arguments. - -##### Returns - -`bytes`[] - -*** - -### any - -#### Get Signature - -> **get** **any**(): [`ValueGenerator`](../../value-generators/classes/ValueGenerator.md) - -Defined in: [src/test-execution-context.ts:93](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L93) - -Returns the value generator. - -##### Returns - -[`ValueGenerator`](../../value-generators/classes/ValueGenerator.md) - -*** - -### contract - -#### Get Signature - -> **get** **contract**(): [`ContractContext`](../../subcontexts/contract-context/classes/ContractContext.md) - -Defined in: [src/test-execution-context.ts:66](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L66) - -Returns the contract context. - -##### Returns - -[`ContractContext`](../../subcontexts/contract-context/classes/ContractContext.md) - -*** - -### defaultSender - -#### Get Signature - -> **get** **defaultSender**(): `Account` - -Defined in: [src/test-execution-context.ts:102](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L102) - -Returns the default sender account. - -##### Returns - -`Account` - -#### Set Signature - -> **set** **defaultSender**(`val`): `void` - -Defined in: [src/test-execution-context.ts:111](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L111) - -Sets the default sender account. - -##### Parameters - -###### val - -The default sender account. - -`bytes` | `Account` - -##### Returns - -`void` - -*** - -### ledger - -#### Get Signature - -> **get** **ledger**(): [`LedgerContext`](../../subcontexts/ledger-context/classes/LedgerContext.md) - -Defined in: [src/test-execution-context.ts:75](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L75) - -Returns the ledger context. - -##### Returns - -[`LedgerContext`](../../subcontexts/ledger-context/classes/LedgerContext.md) - -*** - -### templateVars - -#### Get Signature - -> **get** **templateVars**(): `Record`\<`string`, `any`\> - -Defined in: [src/test-execution-context.ts:129](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L129) - -Returns the template variables. - -##### Returns - -`Record`\<`string`, `any`\> - -*** - -### txn - -#### Get Signature - -> **get** **txn**(): [`TransactionContext`](../../subcontexts/transaction-context/classes/TransactionContext.md) - -Defined in: [src/test-execution-context.ts:84](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L84) - -Returns the transaction context. - -##### Returns - -[`TransactionContext`](../../subcontexts/transaction-context/classes/TransactionContext.md) - -## Methods - -### addApplicationSpy() - -> **addApplicationSpy**\<`TContract`\>(`spy`): `void` - -Defined in: [src/test-execution-context.ts:197](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L197) - -Adds an application spy to the context. - -#### Type Parameters - -##### TContract - -`TContract` *extends* `Contract` - -#### Parameters - -##### spy - -[`ApplicationSpy`](ApplicationSpy.md)\<`TContract`\> - -The application spy to add. - -#### Returns - -`void` - -*** - -### executeLogicSig() - -> **executeLogicSig**(`logicSig`, ...`args`): `boolean` \| `uint64` - -Defined in: [src/test-execution-context.ts:140](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L140) - -Executes a logic signature with the given arguments. - -#### Parameters - -##### logicSig - -`LogicSig` - -The logic signature to execute. - -##### args - -...`bytes`[] - -The arguments for the logic signature. - -#### Returns - -`boolean` \| `uint64` - -*** - -### exportLogs() - -> **exportLogs**\<`T`\>(`appId`, ...`decoding`): `DecodedLogs`\<`T`\> - -Defined in: [src/test-execution-context.ts:57](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L57) - -Exports logs for a given application ID and decoding. - -#### Type Parameters - -##### T - -`T` *extends* `LogDecoding`[] - -#### Parameters - -##### appId - -`uint64` - -The application ID. - -##### decoding - -...`T` - -The log decoding. - -#### Returns - -`DecodedLogs`\<`T`\> - -*** - -### getCompiledAppEntry() - -> **getCompiledAppEntry**(`contract`): `undefined` \| \{ `key`: `ConstructorFor`\<`BaseContract`\>; `value`: `uint64`; \} - -Defined in: [src/test-execution-context.ts:166](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L166) - -Gets a compiled application by contract. - -#### Parameters - -##### contract - -`ConstructorFor`\<`BaseContract`\> - -The contract class. - -#### Returns - -`undefined` \| \{ `key`: `ConstructorFor`\<`BaseContract`\>; `value`: `uint64`; \} - -*** - -### getCompiledLogicSigEntry() - -> **getCompiledLogicSigEntry**(`logicsig`): `undefined` \| \{ `key`: `ConstructorFor`\<`LogicSig`\>; `value`: `Account`; \} - -Defined in: [src/test-execution-context.ts:207](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L207) - -Gets a compiled logic signature. - -#### Parameters - -##### logicsig - -`ConstructorFor`\<`LogicSig`\> - -The logic signature class. - -#### Returns - -`undefined` \| \{ `key`: `ConstructorFor`\<`LogicSig`\>; `value`: `Account`; \} - -*** - -### notifyApplicationSpies() - -> **notifyApplicationSpies**(`itxn`): `void` - -Defined in: [src/test-execution-context.ts:186](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L186) - -#### Parameters - -##### itxn - -`ApplicationCallInnerTxnContext` - -#### Returns - -`void` - -*** - -### reset() - -> **reset**(): `void` - -Defined in: [src/test-execution-context.ts:230](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L230) - -Reinitializes the execution context, clearing all state variables and resetting internal components. -Invoked between test cases to ensure isolation. - -#### Returns - -`void` - -*** - -### setCompiledApp() - -> **setCompiledApp**(`c`, `appId`): `void` - -Defined in: [src/test-execution-context.ts:176](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L176) - -Sets a compiled application. - -#### Parameters - -##### c - -`ConstructorFor`\<`BaseContract`\> - -The contract class. - -##### appId - -`uint64` - -The application ID. - -#### Returns - -`void` - -*** - -### setCompiledLogicSig() - -> **setCompiledLogicSig**(`c`, `account`): `void` - -Defined in: [src/test-execution-context.ts:217](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L217) - -Sets a compiled logic signature. - -#### Parameters - -##### c - -`ConstructorFor`\<`LogicSig`\> - -The logic signature class. - -##### account - -`Account` - -The account associated with the logic signature. - -#### Returns - -`void` - -*** - -### setTemplateVar() - -> **setTemplateVar**(`name`, `value`, `prefix`?): `void` - -Defined in: [src/test-execution-context.ts:156](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-execution-context.ts#L156) - -Sets a template variable. - -#### Parameters - -##### name - -`string` - -The name of the template variable. - -##### value - -`any` - -The value of the template variable. - -##### prefix? - -`string` - -The prefix for the template variable. - -#### Returns - -`void` diff --git a/docs/code/index/functions/addEqualityTesters.md b/docs/code/index/functions/addEqualityTesters.md deleted file mode 100644 index b67e49a..0000000 --- a/docs/code/index/functions/addEqualityTesters.md +++ /dev/null @@ -1,42 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / addEqualityTesters - -# Function: addEqualityTesters() - -> **addEqualityTesters**(`params`): `void` - -Defined in: [src/set-up.ts:159](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/set-up.ts#L159) - -Adds custom equality testers for Algorand types to vitest's expect function. -This allows vitest to properly compare Algorand types such as uint64, biguint, and bytes -against JS native types such as number, bigint and Uint8Array, in tests. - -## Parameters - -### params - -The parameters object - -#### expect - -`ExpectObj` - -vitest's expect object to extend with custom equality testers - -## Returns - -`void` - -## Example - -```ts -import { beforeAll, expect } from 'vitest' -import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'; - -beforeAll(() => { - addEqualityTesters({ expect }); -}); -``` diff --git a/docs/code/index/functions/toExternalValue.md b/docs/code/index/functions/toExternalValue.md deleted file mode 100644 index b0bb3dc..0000000 --- a/docs/code/index/functions/toExternalValue.md +++ /dev/null @@ -1,135 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [index](../README.md) / toExternalValue - -# Function: toExternalValue() - -## Call Signature - -> **toExternalValue**(`val`): `bigint` - -Defined in: [src/impl/primitives.ts:43](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L43) - -Converts internal Algorand type representations to their external primitive values. - -### Parameters - -#### val - -`uint64` - -A uint64 value to convert - -### Returns - -`bigint` - -The uint64 value as a bigint - -### Example - -```ts -const uint64Val = Uint64(123n) -toExternalValue(uint64Val) // returns 123n - -const bytesVal = Bytes.fromBase64("SGVsbG8="); -toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) -``` - -## Call Signature - -> **toExternalValue**(`val`): `bigint` - -Defined in: [src/impl/primitives.ts:44](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L44) - -Converts internal Algorand type representations to their external primitive values. - -### Parameters - -#### val - -`biguint` - -A uint64 value to convert - -### Returns - -`bigint` - -The uint64 value as a bigint - -### Example - -```ts -const uint64Val = Uint64(123n) -toExternalValue(uint64Val) // returns 123n - -const bytesVal = Bytes.fromBase64("SGVsbG8="); -toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) -``` - -## Call Signature - -> **toExternalValue**(`val`): `Uint8Array` - -Defined in: [src/impl/primitives.ts:45](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L45) - -Converts internal Algorand type representations to their external primitive values. - -### Parameters - -#### val - -`bytes` - -A uint64 value to convert - -### Returns - -`Uint8Array` - -The uint64 value as a bigint - -### Example - -```ts -const uint64Val = Uint64(123n) -toExternalValue(uint64Val) // returns 123n - -const bytesVal = Bytes.fromBase64("SGVsbG8="); -toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) -``` - -## Call Signature - -> **toExternalValue**(`val`): `string` - -Defined in: [src/impl/primitives.ts:46](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/impl/primitives.ts#L46) - -Converts internal Algorand type representations to their external primitive values. - -### Parameters - -#### val - -`string` - -A uint64 value to convert - -### Returns - -`string` - -The uint64 value as a bigint - -### Example - -```ts -const uint64Val = Uint64(123n) -toExternalValue(uint64Val) // returns 123n - -const bytesVal = Bytes.fromBase64("SGVsbG8="); -toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) -``` diff --git a/docs/code/subcontexts/contract-context/README.md b/docs/code/subcontexts/contract-context/README.md deleted file mode 100644 index 0e52d7d..0000000 --- a/docs/code/subcontexts/contract-context/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / subcontexts/contract-context - -# subcontexts/contract-context - -## Classes - -- [ContractContext](classes/ContractContext.md) diff --git a/docs/code/subcontexts/contract-context/classes/ContractContext.md b/docs/code/subcontexts/contract-context/classes/ContractContext.md deleted file mode 100644 index f95ae0a..0000000 --- a/docs/code/subcontexts/contract-context/classes/ContractContext.md +++ /dev/null @@ -1,124 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/contract-context](../README.md) / ContractContext - -# Class: ContractContext - -Defined in: [src/subcontexts/contract-context.ts:162](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/contract-context.ts#L162) - -Provides a context for creating contracts and registering created contract instances -with test execution context. - -## Constructors - -### Constructor - -> **new ContractContext**(): `ContractContext` - -#### Returns - -`ContractContext` - -## Methods - -### create() - -> **create**\<`T`\>(`type`, ...`args`): `T` - -Defined in: [src/subcontexts/contract-context.ts:174](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/contract-context.ts#L174) - -Creates a new contract instance and register the created instance with test execution context. - -#### Type Parameters - -##### T - -`T` *extends* `BaseContract` - -Type of contract extending BaseContract - -#### Parameters - -##### type - -`IConstructor`\<`T`\> - -The contract class constructor - -##### args - -...`any`[] - -Constructor arguments for the contract - -#### Returns - -`T` - -Proxied instance of the contract - -#### Example - -```ts -const ctx = new TestExecutionContext(); -const contract = ctx.contract.create(MyContract); -``` - -*** - -### createMethodCallTxns() - -> `static` **createMethodCallTxns**\<`TParams`\>(`contract`, `abiMetadata`, ...`args`): `Transaction`[] - -Defined in: [src/subcontexts/contract-context.ts:196](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/contract-context.ts#L196) - -**`Internal`** - -Creates an array of transactions for calling a contract method. - -#### Type Parameters - -##### TParams - -`TParams` *extends* `unknown`[] - -Array of parameter types - -#### Parameters - -##### contract - -`BaseContract` - -The contract instance - -##### abiMetadata - -ABI metadata for the method - -`undefined` | `AbiMetadata` - -##### args - -...`TParams` - -Method arguments - -#### Returns - -`Transaction`[] - -Array of transactions needed to execute the method - -#### Example - -```ts -const txns = ContractContext.createMethodCallTxns( - myContract, - methodAbiMetadata, - arg1, - arg2 -); -``` diff --git a/docs/code/subcontexts/ledger-context/README.md b/docs/code/subcontexts/ledger-context/README.md deleted file mode 100644 index 3572c51..0000000 --- a/docs/code/subcontexts/ledger-context/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / subcontexts/ledger-context - -# subcontexts/ledger-context - -## Classes - -- [LedgerContext](classes/LedgerContext.md) diff --git a/docs/code/subcontexts/ledger-context/classes/LedgerContext.md b/docs/code/subcontexts/ledger-context/classes/LedgerContext.md deleted file mode 100644 index 2085c7f..0000000 --- a/docs/code/subcontexts/ledger-context/classes/LedgerContext.md +++ /dev/null @@ -1,832 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/ledger-context](../README.md) / LedgerContext - -# Class: LedgerContext - -Defined in: [src/subcontexts/ledger-context.ts:33](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L33) - -## Constructors - -### Constructor - -> **new LedgerContext**(): `LedgerContext` - -#### Returns - -`LedgerContext` - -## Properties - -### accountDataMap - -> **accountDataMap**: `AccountMap`\<`AccountData`\> - -Defined in: [src/subcontexts/ledger-context.ts:38](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L38) - -*** - -### appIdContractMap - -> **appIdContractMap**: `Uint64Map`\<`BaseContract`\> - -Defined in: [src/subcontexts/ledger-context.ts:37](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L37) - -*** - -### appIdIter - -> **appIdIter**: `Generator`\<`bigint`, `any`, `any`\> - -Defined in: [src/subcontexts/ledger-context.ts:34](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L34) - -*** - -### applicationDataMap - -> **applicationDataMap**: `Uint64Map`\<`ApplicationData`\> - -Defined in: [src/subcontexts/ledger-context.ts:36](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L36) - -*** - -### assetDataMap - -> **assetDataMap**: `Uint64Map`\<`Mutable`\<`Omit`\<`Asset`, `"id"` \| `"balance"` \| `"frozen"`\>\>\> - -Defined in: [src/subcontexts/ledger-context.ts:39](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L39) - -*** - -### assetIdIter - -> **assetIdIter**: `Generator`\<`bigint`, `any`, `any`\> - -Defined in: [src/subcontexts/ledger-context.ts:35](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L35) - -*** - -### blocks - -> **blocks**: `Uint64Map`\<`BlockData`\> - -Defined in: [src/subcontexts/ledger-context.ts:41](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L41) - -*** - -### globalData - -> **globalData**: `GlobalData` - -Defined in: [src/subcontexts/ledger-context.ts:42](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L42) - -*** - -### onlineStake - -> **onlineStake**: `number` = `0` - -Defined in: [src/subcontexts/ledger-context.ts:43](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L43) - -*** - -### voterDataMap - -> **voterDataMap**: `AccountMap`\<`VoterData`\> - -Defined in: [src/subcontexts/ledger-context.ts:40](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L40) - -## Methods - -### addAppIdContractMap() - -> **addAppIdContractMap**(`appId`, `contract`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:51](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L51) - -**`Internal`** - -Adds a contract to the application ID contract map. - -#### Parameters - -##### appId - -`StubUint64Compat` - -The application ID. - -##### contract - -`BaseContract` - -The contract to add. - -#### Returns - -`void` - -*** - -### boxExists() - -> **boxExists**(`app`, `key`): `boolean` - -Defined in: [src/subcontexts/ledger-context.ts:411](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L411) - -Checks if a box exists for an application by key. - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -#### Returns - -`boolean` - -True if the box exists, false otherwise. - -*** - -### deleteBox() - -> **deleteBox**(`app`, `key`): `boolean` - -Defined in: [src/subcontexts/ledger-context.ts:398](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L398) - -Deletes a box for an application by key. - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -#### Returns - -`boolean` - -True if the box was deleted, false otherwise. - -*** - -### getAccount() - -> **getAccount**(`address`): `Account` - -Defined in: [src/subcontexts/ledger-context.ts:60](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L60) - -Retrieves an account by address. - -#### Parameters - -##### address - -The account address. - -`StubBytesCompat` | `Account` - -#### Returns - -`Account` - -The account. - -*** - -### getApplication() - -> **getApplication**(`applicationId`): `Application` - -Defined in: [src/subcontexts/ledger-context.ts:83](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L83) - -Retrieves an application by application ID. - -#### Parameters - -##### applicationId - -`StubUint64Compat` - -The application ID. - -#### Returns - -`Application` - -The application. - -#### Throws - -If the application is unknown. - -*** - -### getApplicationForApprovalProgram() - -> **getApplicationForApprovalProgram**(`approvalProgram`): `undefined` \| `Application` - -Defined in: [src/subcontexts/ledger-context.ts:112](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L112) - -Retrieves an application for a given approval program. - -#### Parameters - -##### approvalProgram - -The approval program. - -`undefined` | `bytes` | readonly `bytes`[] - -#### Returns - -`undefined` \| `Application` - -The application or undefined if not found. - -*** - -### getApplicationForContract() - -> **getApplicationForContract**(`contract`): `Application` - -Defined in: [src/subcontexts/ledger-context.ts:96](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L96) - -Retrieves an application for a given contract. - -#### Parameters - -##### contract - -`BaseContract` - -The contract. - -#### Returns - -`Application` - -The application. - -#### Throws - -If the contract is unknown. - -*** - -### getAsset() - -> **getAsset**(`assetId`): `Asset` - -Defined in: [src/subcontexts/ledger-context.ts:70](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L70) - -Retrieves an asset by asset ID. - -#### Parameters - -##### assetId - -`StubUint64Compat` - -The asset ID. - -#### Returns - -`Asset` - -The asset. - -#### Throws - -If the asset is unknown. - -*** - -### getBlockData() - -> **getBlockData**(`index`): `BlockData` - -Defined in: [src/subcontexts/ledger-context.ts:246](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L246) - -Retrieves block data by index. - -#### Parameters - -##### index - -`StubUint64Compat` - -The block index. - -#### Returns - -`BlockData` - -The block data. - -#### Throws - -If the block is not set. - -*** - -### getBox() - -> **getBox**(`app`, `key`): `Uint8Array` - -Defined in: [src/subcontexts/ledger-context.ts:341](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L341) - -Retrieves a box for an application by key. - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -#### Returns - -`Uint8Array` - -The box data. - -*** - -### getGlobalState() - -> **getGlobalState**(`app`, `key`): \[`GlobalStateCls`\<`unknown`\>, `true`\] \| \[`undefined`, `false`\] - -Defined in: [src/subcontexts/ledger-context.ts:260](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L260) - -Retrieves global state for an application by key. - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -#### Returns - -\[`GlobalStateCls`\<`unknown`\>, `true`\] \| \[`undefined`, `false`\] - -The global state and a boolean indicating if it was found. - -*** - -### getLocalState() - -> **getLocalState**(`app`, `account`, `key`): \[`undefined`, `false`\] \| \[`LocalStateForAccount`\<`unknown`\>, `true`\] - -Defined in: [src/subcontexts/ledger-context.ts:295](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L295) - -Retrieves local state for an application and account by key. - -#### Parameters - -##### app - -The application. - -`uint64` | `BaseContract` | `Application` - -##### account - -`Account` - -The account. - -##### key - -`StubBytesCompat` - -The key. - -#### Returns - -\[`undefined`, `false`\] \| \[`LocalStateForAccount`\<`unknown`\>, `true`\] - -The local state and a boolean indicating if it was found. - -*** - -### getMaterialisedBox() - -> **getMaterialisedBox**\<`T`\>(`app`, `key`): `undefined` \| `T` - -Defined in: [src/subcontexts/ledger-context.ts:358](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L358) - -**`Internal`** - -Retrieves a materialised box for an application by key. - -#### Type Parameters - -##### T - -`T` - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -#### Returns - -`undefined` \| `T` - -The materialised box data if exists or undefined. - -*** - -### patchAccountData() - -> **patchAccountData**(`account`, `data`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:168](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L168) - -Patches account data with the provided partial data. - -#### Parameters - -##### account - -`Account` - -The account. - -##### data - -`Partial`\<`Omit`\<`AccountData`, `"account"`\>\> & `Partial`\<`PickPartial`\<`AccountData`, `"account"`\>\> - -The partial account data. - -#### Returns - -`void` - -*** - -### patchApplicationData() - -> **patchApplicationData**(`app`, `data`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:185](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L185) - -Patches application data with the provided partial data. - -#### Parameters - -##### app - -`Application` - -The application. - -##### data - -`Partial`\<`Omit`\<`ApplicationData`, `"application"`\>\> & `Partial`\<`PickPartial`\<`ApplicationData`, `"application"`\>\> - -The partial application data. - -#### Returns - -`void` - -*** - -### patchAssetData() - -> **patchAssetData**(`asset`, `data`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:205](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L205) - -Patches asset data with the provided partial data. - -#### Parameters - -##### asset - -`Asset` - -##### data - -`Partial`\<`Mutable`\<`Omit`\<`Asset`, `"id"` \| `"balance"` \| `"frozen"`\>\>\> - -The partial asset data. - -#### Returns - -`void` - -*** - -### patchBlockData() - -> **patchBlockData**(`index`, `data`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:231](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L231) - -Patches block data with the provided partial data. - -#### Parameters - -##### index - -`StubUint64Compat` - -The block index. - -##### data - -`Partial`\<`BlockData`\> - -The partial block data. - -#### Returns - -`void` - -*** - -### patchGlobalData() - -> **patchGlobalData**(`data`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:156](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L156) - -Patches global data with the provided partial data. - -#### Parameters - -##### data - -`Partial`\<`GlobalData`\> - -The partial global data. - -#### Returns - -`void` - -*** - -### patchVoterData() - -> **patchVoterData**(`account`, `data`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:218](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L218) - -Patches voter data with the provided partial data. - -#### Parameters - -##### account - -`Account` - -The account. - -##### data - -`Partial`\<`VoterData`\> - -The partial voter data. - -#### Returns - -`void` - -*** - -### setBox() - -> **setBox**(`app`, `key`, `value`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:370](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L370) - -Sets a box for an application by key. - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -##### value - -The box data. - -`Uint8Array`\<`ArrayBufferLike`\> | `StubBytesCompat` - -#### Returns - -`void` - -*** - -### setGlobalState() - -> **setGlobalState**(`app`, `key`, `value`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:275](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L275) - -Sets global state for an application by key. - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -##### value - -The value (optional). - -`undefined` | `StubBytesCompat` | `StubUint64Compat` - -#### Returns - -`void` - -*** - -### setLocalState() - -> **setLocalState**\<`T`\>(`app`, `account`, `key`, `value`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:317](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L317) - -Sets local state for an application and account by key. - -#### Type Parameters - -##### T - -`T` - -#### Parameters - -##### app - -The application. - -`uint64` | `BaseContract` | `Application` - -##### account - -`Account` - -The account. - -##### key - -`StubBytesCompat` - -The key. - -##### value - -The value (optional). - -`undefined` | `T` - -#### Returns - -`void` - -*** - -### setMatrialisedBox() - -> **setMatrialisedBox**\<`TValue`\>(`app`, `key`, `value`): `void` - -Defined in: [src/subcontexts/ledger-context.ts:386](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L386) - -**`Internal`** - -Cache the materialised box for an application by key. - -#### Type Parameters - -##### TValue - -`TValue` - -#### Parameters - -##### app - -The application. - -`BaseContract` | `Application` - -##### key - -`StubBytesCompat` - -The key. - -##### value - -The box data. - -`undefined` | `TValue` - -#### Returns - -`void` - -*** - -### updateAssetHolding() - -> **updateAssetHolding**(`account`, `assetId`, `balance`?, `frozen`?): `void` - -Defined in: [src/subcontexts/ledger-context.ts:142](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/ledger-context.ts#L142) - -Update asset holdings for account, only specified values will be updated. -AccountType will also be opted-in to asset - -#### Parameters - -##### account - -`Account` - -##### assetId - -`StubUint64Compat` | `Asset` - -##### balance? - -`StubUint64Compat` - -##### frozen? - -`boolean` - -#### Returns - -`void` diff --git a/docs/code/subcontexts/transaction-context/README.md b/docs/code/subcontexts/transaction-context/README.md deleted file mode 100644 index 32e8d08..0000000 --- a/docs/code/subcontexts/transaction-context/README.md +++ /dev/null @@ -1,14 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / subcontexts/transaction-context - -# subcontexts/transaction-context - -## Classes - -- [DeferredAppCall](classes/DeferredAppCall.md) -- [ItxnGroup](classes/ItxnGroup.md) -- [TransactionContext](classes/TransactionContext.md) -- [TransactionGroup](classes/TransactionGroup.md) diff --git a/docs/code/subcontexts/transaction-context/classes/DeferredAppCall.md b/docs/code/subcontexts/transaction-context/classes/DeferredAppCall.md deleted file mode 100644 index 11014f8..0000000 --- a/docs/code/subcontexts/transaction-context/classes/DeferredAppCall.md +++ /dev/null @@ -1,79 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / DeferredAppCall - -# Class: DeferredAppCall\ - -Defined in: [src/subcontexts/transaction-context.ts:59](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L59) - -Represents a deferred application call. - -## Type Parameters - -### TParams - -`TParams` *extends* `unknown`[] - -### TReturn - -`TReturn` - -## Constructors - -### Constructor - -> **new DeferredAppCall**\<`TParams`, `TReturn`\>(`appId`, `txns`, `method`, `abiMetadata`, `args`): `DeferredAppCall`\<`TParams`, `TReturn`\> - -Defined in: [src/subcontexts/transaction-context.ts:60](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L60) - -#### Parameters - -##### appId - -`uint64` - -##### txns - -`Transaction`[] - -##### method - -(...`args`) => `TReturn` - -##### abiMetadata - -`AbiMetadata` - -##### args - -`TParams` - -#### Returns - -`DeferredAppCall`\<`TParams`, `TReturn`\> - -## Properties - -### txns - -> `readonly` **txns**: `Transaction`[] - -Defined in: [src/subcontexts/transaction-context.ts:62](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L62) - -## Methods - -### submit() - -> **submit**(): `TReturn` - -Defined in: [src/subcontexts/transaction-context.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L72) - -Submits the deferred application call. - -#### Returns - -`TReturn` - -The result of the application call. diff --git a/docs/code/subcontexts/transaction-context/classes/ItxnGroup.md b/docs/code/subcontexts/transaction-context/classes/ItxnGroup.md deleted file mode 100644 index 10a5bf2..0000000 --- a/docs/code/subcontexts/transaction-context/classes/ItxnGroup.md +++ /dev/null @@ -1,205 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / ItxnGroup - -# Class: ItxnGroup - -Defined in: [src/subcontexts/transaction-context.ts:496](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L496) - -Represents a group of inner transactions. - -## Constructors - -### Constructor - -> **new ItxnGroup**(`itxns`): `ItxnGroup` - -Defined in: [src/subcontexts/transaction-context.ts:498](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L498) - -#### Parameters - -##### itxns - -`InnerTxn`[] - -#### Returns - -`ItxnGroup` - -## Properties - -### itxns - -> **itxns**: `InnerTxn`[] = `[]` - -Defined in: [src/subcontexts/transaction-context.ts:497](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L497) - -## Methods - -### getApplicationCallInnerTxn() - -> **getApplicationCallInnerTxn**(`index`?): `ApplicationCallInnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:507](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L507) - -Gets an application inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`ApplicationCallInnerTxn` - -The application inner transaction. - -*** - -### getAssetConfigInnerTxn() - -> **getAssetConfigInnerTxn**(`index`?): `AssetConfigInnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:516](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L516) - -Gets an asset configuration inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`AssetConfigInnerTxn` - -The asset configuration inner transaction. - -*** - -### getAssetFreezeInnerTxn() - -> **getAssetFreezeInnerTxn**(`index`?): `AssetFreezeInnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:534](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L534) - -Gets an asset freeze inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`AssetFreezeInnerTxn` - -The asset freeze inner transaction. - -*** - -### getAssetTransferInnerTxn() - -> **getAssetTransferInnerTxn**(`index`?): `AssetTransferInnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:525](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L525) - -Gets an asset transfer inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`AssetTransferInnerTxn` - -The asset transfer inner transaction. - -*** - -### getInnerTxn() - -> **getInnerTxn**(`index`?): `InnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:561](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L561) - -Gets an inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`InnerTxn` - -The inner transaction. - -*** - -### getKeyRegistrationInnerTxn() - -> **getKeyRegistrationInnerTxn**(`index`?): `KeyRegistrationInnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:543](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L543) - -Gets a key registration inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`KeyRegistrationInnerTxn` - -The key registration inner transaction. - -*** - -### getPaymentInnerTxn() - -> **getPaymentInnerTxn**(`index`?): `PaymentInnerTxn` - -Defined in: [src/subcontexts/transaction-context.ts:552](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L552) - -Gets a payment inner transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`PaymentInnerTxn` - -The payment inner transaction. diff --git a/docs/code/subcontexts/transaction-context/classes/TransactionContext.md b/docs/code/subcontexts/transaction-context/classes/TransactionContext.md deleted file mode 100644 index 7d27b90..0000000 --- a/docs/code/subcontexts/transaction-context/classes/TransactionContext.md +++ /dev/null @@ -1,273 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / TransactionContext - -# Class: TransactionContext - -Defined in: [src/subcontexts/transaction-context.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L81) - -Manages transaction contexts and groups. - -## Constructors - -### Constructor - -> **new TransactionContext**(): `TransactionContext` - -#### Returns - -`TransactionContext` - -## Properties - -### groups - -> `readonly` **groups**: [`TransactionGroup`](TransactionGroup.md)[] = `[]` - -Defined in: [src/subcontexts/transaction-context.ts:82](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L82) - -## Accessors - -### activeGroup - -#### Get Signature - -> **get** **activeGroup**(): [`TransactionGroup`](TransactionGroup.md) - -Defined in: [src/subcontexts/transaction-context.ts:148](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L148) - -Gets the active transaction group. - -##### Throws - -If there is no active transaction group. - -##### Returns - -[`TransactionGroup`](TransactionGroup.md) - -The active transaction group. - -*** - -### lastActive - -#### Get Signature - -> **get** **lastActive**(): `Transaction` - -Defined in: [src/subcontexts/transaction-context.ts:171](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L171) - -Gets the last active transaction. - -##### Returns - -`Transaction` - -The last active transaction. - -*** - -### lastGroup - -#### Get Signature - -> **get** **lastGroup**(): [`TransactionGroup`](TransactionGroup.md) - -Defined in: [src/subcontexts/transaction-context.ts:160](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L160) - -Gets the last transaction group. - -##### Throws - -If there are no transaction groups. - -##### Returns - -[`TransactionGroup`](TransactionGroup.md) - -The last transaction group. - -## Methods - -### appendLog() - -> **appendLog**(`value`): `void` - -Defined in: [src/subcontexts/transaction-context.ts:181](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L181) - -**`Internal`** - -Appends a log to the active transaction. - -#### Parameters - -##### value - -`StubBytesCompat` - -The log value. - -#### Returns - -`void` - -#### Throws - -If the active transaction is not an application call. - -*** - -### createScope() - -> **createScope**(`group`, `activeTransactionIndex`?): `ExecutionScope` - -Defined in: [src/subcontexts/transaction-context.ts:91](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L91) - -Creates a new execution scope for a group of transactions. - -#### Parameters - -##### group - -(`Transaction` \| [`DeferredAppCall`](DeferredAppCall.md)\<`any`[], `any`\>)[] - -The group of transactions or deferred application calls. - -##### activeTransactionIndex? - -`number` - -The index of the active transaction. - -#### Returns - -`ExecutionScope` - -The execution scope. - -*** - -### deferAppCall() - -> **deferAppCall**\<`TContract`, `TParams`, `TReturn`\>(`contract`, `method`, `methodName`, ...`args`): [`DeferredAppCall`](DeferredAppCall.md)\<`TParams`, `TReturn`\> - -Defined in: [src/subcontexts/transaction-context.ts:197](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L197) - -Defers an application call. - -#### Type Parameters - -##### TContract - -`TContract` *extends* `Contract` - -##### TParams - -`TParams` *extends* `unknown`[] - -##### TReturn - -`TReturn` - -#### Parameters - -##### contract - -`TContract` - -The contract. - -##### method - -(...`args`) => `TReturn` - -The method to call. - -##### methodName - -`FunctionKeys`\<`TContract`\> - -The name of the method. - -##### args - -...`TParams` - -The arguments for the method. - -#### Returns - -[`DeferredAppCall`](DeferredAppCall.md)\<`TParams`, `TReturn`\> - -The deferred application call. - -*** - -### ensureScope() - -> **ensureScope**(`group`, `activeTransactionIndex`?): `ExecutionScope` - -Defined in: [src/subcontexts/transaction-context.ts:132](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L132) - -**`Internal`** - -Ensures that a scope is created for the given group of transactions. - -#### Parameters - -##### group - -`Transaction`[] - -The group of transactions. - -##### activeTransactionIndex? - -`number` - -The index of the active transaction. - -#### Returns - -`ExecutionScope` - -The execution scope. - -*** - -### exportLogs() - -> **exportLogs**\<`T`\>(`appId`, ...`decoding`): `DecodedLogs`\<`T`\> - -Defined in: [src/subcontexts/transaction-context.ts:215](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L215) - -Exports logs for the given application ID. - -#### Type Parameters - -##### T - -`T` *extends* `LogDecoding`[] - -#### Parameters - -##### appId - -`uint64` - -The application ID. - -##### decoding - -...`T` - -The log decoding. - -#### Returns - -`DecodedLogs`\<`T`\> - -The decoded logs. diff --git a/docs/code/subcontexts/transaction-context/classes/TransactionGroup.md b/docs/code/subcontexts/transaction-context/classes/TransactionGroup.md deleted file mode 100644 index b16e01f..0000000 --- a/docs/code/subcontexts/transaction-context/classes/TransactionGroup.md +++ /dev/null @@ -1,485 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [subcontexts/transaction-context](../README.md) / TransactionGroup - -# Class: TransactionGroup - -Defined in: [src/subcontexts/transaction-context.ts:233](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L233) - -Represents a group of transactions. - -## Constructors - -### Constructor - -> **new TransactionGroup**(`transactions`, `activeTransactionIndex`?): `TransactionGroup` - -Defined in: [src/subcontexts/transaction-context.ts:240](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L240) - -#### Parameters - -##### transactions - -`Transaction`[] - -##### activeTransactionIndex? - -`number` - -#### Returns - -`TransactionGroup` - -## Properties - -### activeTransactionIndex - -> **activeTransactionIndex**: `number` - -Defined in: [src/subcontexts/transaction-context.ts:234](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L234) - -*** - -### constructingItxnGroup - -> **constructingItxnGroup**: `InnerTxnFields`[] = `[]` - -Defined in: [src/subcontexts/transaction-context.ts:238](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L238) - -*** - -### itxnGroups - -> **itxnGroups**: [`ItxnGroup`](ItxnGroup.md)[] = `[]` - -Defined in: [src/subcontexts/transaction-context.ts:237](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L237) - -*** - -### latestTimestamp - -> **latestTimestamp**: `number` - -Defined in: [src/subcontexts/transaction-context.ts:235](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L235) - -*** - -### transactions - -> **transactions**: `Transaction`[] - -Defined in: [src/subcontexts/transaction-context.ts:236](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L236) - -## Accessors - -### activeApplicationId - -#### Get Signature - -> **get** **activeApplicationId**(): `uint64` - -Defined in: [src/subcontexts/transaction-context.ts:263](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L263) - -Gets the active application ID. - -##### Throws - -If there are no transactions in the group or the active transaction is not an application call. - -##### Returns - -`uint64` - -The active application ID. - -*** - -### activeTransaction - -#### Get Signature - -> **get** **activeTransaction**(): `Transaction` - -Defined in: [src/subcontexts/transaction-context.ts:254](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L254) - -Gets the active transaction. - -##### Returns - -`Transaction` - -The active transaction. - -*** - -### constructingItxn - -#### Get Signature - -> **get** **constructingItxn**(): `InnerTxnFields` - -Defined in: [src/subcontexts/transaction-context.ts:273](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L273) - -##### Returns - -`InnerTxnFields` - -## Methods - -### addInnerTransactionGroup() - -> **addInnerTransactionGroup**(...`itxns`): `void` - -Defined in: [src/subcontexts/transaction-context.ts:312](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L312) - -**`Internal`** - -Adds a group of inner transactions. - -#### Parameters - -##### itxns - -...`InnerTxn`[] - -The inner transactions. - -#### Returns - -`void` - -*** - -### appendInnerTransactionGroup() - -> **appendInnerTransactionGroup**(): `void` - -Defined in: [src/subcontexts/transaction-context.ts:337](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L337) - -**`Internal`** - -Appends a new inner transaction to the current group. - -#### Returns - -`void` - -#### Throws - -If there is no inner transaction group being constructed. - -*** - -### beginInnerTransactionGroup() - -> **beginInnerTransactionGroup**(): `void` - -Defined in: [src/subcontexts/transaction-context.ts:321](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L321) - -**`Internal`** - -Begins a new inner transaction group. - -#### Returns - -`void` - -#### Throws - -If there is already an inner transaction group being constructed or the active transaction is not an application call. - -*** - -### getApplicationCallTransaction() - -> **getApplicationCallTransaction**(`index`?): `ApplicationCallTransaction` - -Defined in: [src/subcontexts/transaction-context.ts:405](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L405) - -Gets an application transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`ApplicationCallTransaction` - -The application transaction. - -*** - -### getAssetConfigTransaction() - -> **getAssetConfigTransaction**(`index`?): `AssetConfigTransaction` - -Defined in: [src/subcontexts/transaction-context.ts:414](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L414) - -Gets an asset configuration transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`AssetConfigTransaction` - -The asset configuration transaction. - -*** - -### getAssetFreezeTransaction() - -> **getAssetFreezeTransaction**(`index`?): `AssetFreezeTransaction` - -Defined in: [src/subcontexts/transaction-context.ts:432](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L432) - -Gets an asset freeze transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`AssetFreezeTransaction` - -The asset freeze transaction. - -*** - -### getAssetTransferTransaction() - -> **getAssetTransferTransaction**(`index`?): `AssetTransferTransaction` - -Defined in: [src/subcontexts/transaction-context.ts:423](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L423) - -Gets an asset transfer transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`AssetTransferTransaction` - -The asset transfer transaction. - -*** - -### getItxnGroup() - -> **getItxnGroup**(`index`?): [`ItxnGroup`](ItxnGroup.md) - -Defined in: [src/subcontexts/transaction-context.ts:387](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L387) - -Gets an inner transaction group by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the group. If not provided, the last group is returned. - -#### Returns - -[`ItxnGroup`](ItxnGroup.md) - -The inner transaction group. - -#### Throws - -If the index is invalid or there are no previous inner transactions. - -*** - -### getKeyRegistrationTransaction() - -> **getKeyRegistrationTransaction**(`index`?): `KeyRegistrationTransaction` - -Defined in: [src/subcontexts/transaction-context.ts:441](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L441) - -Gets a key registration transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`KeyRegistrationTransaction` - -The key registration transaction. - -*** - -### getPaymentTransaction() - -> **getPaymentTransaction**(`index`?): `PaymentTransaction` - -Defined in: [src/subcontexts/transaction-context.ts:450](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L450) - -Gets a payment transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`PaymentTransaction` - -The payment transaction. - -*** - -### getScratchSlot() - -> **getScratchSlot**(`index`): `uint64` \| `bytes` - -Defined in: [src/subcontexts/transaction-context.ts:293](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L293) - -Gets the scratch slot of the active transaction. - -#### Parameters - -##### index - -`StubUint64Compat` - -The index of the scratch slot. - -#### Returns - -`uint64` \| `bytes` - -The scratch slot value. - -*** - -### getScratchSpace() - -> **getScratchSpace**(): (`uint64` \| `bytes`)[] - -Defined in: [src/subcontexts/transaction-context.ts:284](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L284) - -Gets the scratch space of the active transaction. - -#### Returns - -(`uint64` \| `bytes`)[] - -The scratch space. - -*** - -### getTransaction() - -> **getTransaction**(`index`?): `Transaction` - -Defined in: [src/subcontexts/transaction-context.ts:459](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L459) - -Gets a transaction by index. - -#### Parameters - -##### index? - -`StubUint64Compat` - -The index of the transaction. - -#### Returns - -`Transaction` - -The transaction. - -*** - -### lastItxnGroup() - -> **lastItxnGroup**(): [`ItxnGroup`](ItxnGroup.md) - -Defined in: [src/subcontexts/transaction-context.ts:377](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L377) - -Gets the last inner transaction group. - -#### Returns - -[`ItxnGroup`](ItxnGroup.md) - -The last inner transaction group. - -*** - -### patchActiveTransactionFields() - -> **patchActiveTransactionFields**(`fields`): `void` - -Defined in: [src/subcontexts/transaction-context.ts:301](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L301) - -Patches the fields of the active transaction. - -#### Parameters - -##### fields - -`AllTransactionFields` - -The fields to patch. - -#### Returns - -`void` - -*** - -### submitInnerTransactionGroup() - -> **submitInnerTransactionGroup**(): `void` - -Defined in: [src/subcontexts/transaction-context.ts:349](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/subcontexts/transaction-context.ts#L349) - -**`Internal`** - -Submits the current inner transaction group. - -#### Returns - -`void` - -#### Throws - -If there is no inner transaction group being constructed or the group exceeds the maximum size. diff --git a/docs/code/test-transformer/jest-transformer/README.md b/docs/code/test-transformer/jest-transformer/README.md deleted file mode 100644 index c00fdef..0000000 --- a/docs/code/test-transformer/jest-transformer/README.md +++ /dev/null @@ -1,13 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / test-transformer/jest-transformer - -# test-transformer/jest-transformer - -## Variables - -- [factory](variables/factory.md) -- [name](variables/name.md) -- [version](variables/version.md) diff --git a/docs/code/test-transformer/jest-transformer/variables/factory.md b/docs/code/test-transformer/jest-transformer/variables/factory.md deleted file mode 100644 index 99a090e..0000000 --- a/docs/code/test-transformer/jest-transformer/variables/factory.md +++ /dev/null @@ -1,52 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/jest-transformer](../README.md) / factory - -# Variable: factory() - -> `const` **factory**: (`compilerInstance`) => `TransformerFactory`\<`SourceFile`\> - -Defined in: [src/test-transformer/jest-transformer.ts:49](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/jest-transformer.ts#L49) - -Factory function that creates TypeScript program transformers for Jest. -Used by ts-jest to transform TypeScript files during test execution. -Initialized with default transformer configuration. - -## Parameters - -### compilerInstance - -#### program - -`Program` - -## Returns - -`TransformerFactory`\<`SourceFile`\> - -## Example - -```ts -// Use as before stage transformer with custom config in jest.config.ts -import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest' - -const presetConfig = createDefaultEsmPreset({}) -const jestConfig: JestConfigWithTsJest = { - ...presetConfig, - transform: { - '^.+\\.tsx?$': [ - 'ts-jest', - { - useESM: true, - astTransformers: { - before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'], - }, - }, - ], - }, - extensionsToTreatAsEsm: ['.ts'], -} -export default jestConfig -``` diff --git a/docs/code/test-transformer/jest-transformer/variables/name.md b/docs/code/test-transformer/jest-transformer/variables/name.md deleted file mode 100644 index 4e5c23f..0000000 --- a/docs/code/test-transformer/jest-transformer/variables/name.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/jest-transformer](../README.md) / name - -# Variable: name - -> `const` **name**: `"puyaTsTransformer"` = `'puyaTsTransformer'` - -Defined in: [src/test-transformer/jest-transformer.ts:15](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/jest-transformer.ts#L15) diff --git a/docs/code/test-transformer/jest-transformer/variables/version.md b/docs/code/test-transformer/jest-transformer/variables/version.md deleted file mode 100644 index 85d81f7..0000000 --- a/docs/code/test-transformer/jest-transformer/variables/version.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/jest-transformer](../README.md) / version - -# Variable: version - -> `const` **version**: `"0.1.0"` = `'0.1.0'` - -Defined in: [src/test-transformer/jest-transformer.ts:16](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/jest-transformer.ts#L16) diff --git a/docs/code/test-transformer/vitest-transformer/README.md b/docs/code/test-transformer/vitest-transformer/README.md deleted file mode 100644 index dead2fa..0000000 --- a/docs/code/test-transformer/vitest-transformer/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / test-transformer/vitest-transformer - -# test-transformer/vitest-transformer - -## Variables - -- [puyaTsTransformer](variables/puyaTsTransformer.md) diff --git a/docs/code/test-transformer/vitest-transformer/variables/puyaTsTransformer.md b/docs/code/test-transformer/vitest-transformer/variables/puyaTsTransformer.md deleted file mode 100644 index dfae2e9..0000000 --- a/docs/code/test-transformer/vitest-transformer/variables/puyaTsTransformer.md +++ /dev/null @@ -1,50 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [test-transformer/vitest-transformer](../README.md) / puyaTsTransformer - -# Variable: puyaTsTransformer - -> `const` **puyaTsTransformer**: `ts.TransformerFactory`\<`ts.SourceFile`\> & (`config`) => `ts.TransformerFactory`\<`ts.SourceFile`\> - -Defined in: [src/test-transformer/vitest-transformer.ts:54](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/test-transformer/vitest-transformer.ts#L54) - -TypeScript transformer for Algorand TypeScript smart contracts and testing files -which is mainly responsilbe for swapping in stub implementations of op codes, -and capturing TypeScript type information for the Node.js runtime. - -* - -## Param - -Configuration options - -## Param - -File extensions to process - -## Param - -Package name for testing imports - -## Example - -```ts -// Use as before stage transformer with custom config in vitest.config.mts -import typescript from '@rollup/plugin-typescript' -import { defineConfig } from 'vitest/config' -import { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer' - -export default defineConfig({ - esbuild: {}, - plugins: [ - typescript({ - tsconfig: './tsconfig.json', - transformers: { - before: [puyaTsTransformer], - }, - }), - ], -}) -``` diff --git a/docs/code/value-generators/README.md b/docs/code/value-generators/README.md deleted file mode 100644 index 5e7671a..0000000 --- a/docs/code/value-generators/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../README.md) / value-generators - -# value-generators - -## Classes - -- [ValueGenerator](classes/ValueGenerator.md) diff --git a/docs/code/value-generators/arc4/README.md b/docs/code/value-generators/arc4/README.md deleted file mode 100644 index 6ef802d..0000000 --- a/docs/code/value-generators/arc4/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / value-generators/arc4 - -# value-generators/arc4 - -## Classes - -- [Arc4ValueGenerator](classes/Arc4ValueGenerator.md) diff --git a/docs/code/value-generators/arc4/classes/Arc4ValueGenerator.md b/docs/code/value-generators/arc4/classes/Arc4ValueGenerator.md deleted file mode 100644 index 8baa1b2..0000000 --- a/docs/code/value-generators/arc4/classes/Arc4ValueGenerator.md +++ /dev/null @@ -1,242 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [value-generators/arc4](../README.md) / Arc4ValueGenerator - -# Class: Arc4ValueGenerator - -Defined in: [src/value-generators/arc4.ts:7](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L7) - -## Constructors - -### Constructor - -> **new Arc4ValueGenerator**(): `Arc4ValueGenerator` - -#### Returns - -`Arc4ValueGenerator` - -## Methods - -### address() - -> **address**(): `Address` - -Defined in: [src/value-generators/arc4.ts:12](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L12) - -Generate a random Algorand address. -@returns: A new, random Algorand address. - -#### Returns - -`Address` - -*** - -### dynamicBytes() - -> **dynamicBytes**(`n`): `DynamicBytes` - -Defined in: [src/value-generators/arc4.ts:97](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L97) - -Generate a random dynamic bytes of size `n` bits. - -#### Parameters - -##### n - -`number` - -#### Returns - -`DynamicBytes` - -*** - -### str() - -> **str**(`n`): `Str` - -Defined in: [src/value-generators/arc4.ts:109](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L109) - -Generate a random dynamic string of size `n` bits. - -#### Parameters - -##### n - -`number` - -#### Returns - -`Str` - -*** - -### uint128() - -> **uint128**(`minValue`, `maxValue`): `Uint128` - -Defined in: [src/value-generators/arc4.ts:67](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L67) - -Generate a random Uint128 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint128` - -*** - -### uint16() - -> **uint16**(`minValue`, `maxValue`): `Uint16` - -Defined in: [src/value-generators/arc4.ts:37](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L37) - -Generate a random Uint16 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint16` - -*** - -### uint256() - -> **uint256**(`minValue`, `maxValue`): `Uint256` - -Defined in: [src/value-generators/arc4.ts:77](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L77) - -Generate a random Uint256 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint256` - -*** - -### uint32() - -> **uint32**(`minValue`, `maxValue`): `Uint32` - -Defined in: [src/value-generators/arc4.ts:47](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L47) - -Generate a random Uint32 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint32` - -*** - -### uint512() - -> **uint512**(`minValue`, `maxValue`): `Uint`\<`512`\> - -Defined in: [src/value-generators/arc4.ts:87](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L87) - -Generate a random Uint512 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint`\<`512`\> - -*** - -### uint64() - -> **uint64**(`minValue`, `maxValue`): `Uint64` - -Defined in: [src/value-generators/arc4.ts:57](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L57) - -Generate a random Uint64 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint64` - -*** - -### uint8() - -> **uint8**(`minValue`, `maxValue`): `Uint8` - -Defined in: [src/value-generators/arc4.ts:27](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/arc4.ts#L27) - -Generate a random Uint8 within the specified range. - -#### Parameters - -##### minValue - -`number` | `bigint` - -##### maxValue - -`number` | `bigint` - -#### Returns - -`Uint8` diff --git a/docs/code/value-generators/avm/README.md b/docs/code/value-generators/avm/README.md deleted file mode 100644 index b528e26..0000000 --- a/docs/code/value-generators/avm/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / value-generators/avm - -# value-generators/avm - -## Classes - -- [AvmValueGenerator](classes/AvmValueGenerator.md) diff --git a/docs/code/value-generators/avm/classes/AvmValueGenerator.md b/docs/code/value-generators/avm/classes/AvmValueGenerator.md deleted file mode 100644 index 1b5fb7e..0000000 --- a/docs/code/value-generators/avm/classes/AvmValueGenerator.md +++ /dev/null @@ -1,197 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [value-generators/avm](../README.md) / AvmValueGenerator - -# Class: AvmValueGenerator - -Defined in: [src/value-generators/avm.ts:31](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L31) - -## Extended by - -- [`ValueGenerator`](../../classes/ValueGenerator.md) - -## Constructors - -### Constructor - -> **new AvmValueGenerator**(): `AvmValueGenerator` - -#### Returns - -`AvmValueGenerator` - -## Methods - -### account() - -> **account**(`input`?): `Account` - -Defined in: [src/value-generators/avm.ts:95](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L95) - -Generates a random account with the specified context data. - -#### Parameters - -##### input? - -`AccountContextData` - -The context data for the account. - -#### Returns - -`Account` - -- A random account. - -*** - -### application() - -> **application**(`input`?): `Application` - -Defined in: [src/value-generators/avm.ts:153](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L153) - -Generates a random application with the specified context data. - -#### Parameters - -##### input? - -`ApplicationContextData` - -The context data for the application. - -#### Returns - -`Application` - -- A random application. - -*** - -### asset() - -> **asset**(`input`?): `Asset` - -Defined in: [src/value-generators/avm.ts:133](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L133) - -Generates a random asset with the specified context data. - -#### Parameters - -##### input? - -`AssetContextData` - -The context data for the asset. - -#### Returns - -`Asset` - -- A random asset. - -*** - -### biguint() - -> **biguint**(`minValue`?): `biguint` - -Defined in: [src/value-generators/avm.ts:58](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L58) - -Generates a random biguint value within the specified range. - -#### Parameters - -##### minValue? - -`StubBigUintCompat` = `0n` - -The minimum value (inclusive). - -#### Returns - -`biguint` - -- A random biguint value. - -*** - -### bytes() - -> **bytes**(`length`?): `bytes` - -Defined in: [src/value-generators/avm.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L72) - -Generates a random bytes of the specified length. - -#### Parameters - -##### length? - -`number` = `MAX_BYTES_SIZE` - -The length of the bytes. - -#### Returns - -`bytes` - -- A random bytes. - -*** - -### string() - -> **string**(`length`?): `string` - -Defined in: [src/value-generators/avm.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L81) - -Generates a random string of the specified length. - -#### Parameters - -##### length? - -`number` = `11` - -The length of the string. - -#### Returns - -`string` - -- A random string. - -*** - -### uint64() - -> **uint64**(`minValue`?, `maxValue`?): `uint64` - -Defined in: [src/value-generators/avm.ts:38](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L38) - -Generates a random uint64 value within the specified range. - -#### Parameters - -##### minValue? - -`StubUint64Compat` = `0n` - -The minimum value (inclusive). - -##### maxValue? - -`StubUint64Compat` = `MAX_UINT64` - -The maximum value (inclusive). - -#### Returns - -`uint64` - -- A random uint64 value. diff --git a/docs/code/value-generators/classes/ValueGenerator.md b/docs/code/value-generators/classes/ValueGenerator.md deleted file mode 100644 index 5568628..0000000 --- a/docs/code/value-generators/classes/ValueGenerator.md +++ /dev/null @@ -1,247 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / [value-generators](../README.md) / ValueGenerator - -# Class: ValueGenerator - -Defined in: [src/value-generators/index.ts:5](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L5) - -## Extends - -- [`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md) - -## Constructors - -### Constructor - -> **new ValueGenerator**(): `ValueGenerator` - -Defined in: [src/value-generators/index.ts:9](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L9) - -#### Returns - -`ValueGenerator` - -#### Overrides - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`constructor`](../avm/classes/AvmValueGenerator.md#constructor) - -## Properties - -### arc4 - -> **arc4**: [`Arc4ValueGenerator`](../arc4/classes/Arc4ValueGenerator.md) - -Defined in: [src/value-generators/index.ts:7](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L7) - -*** - -### txn - -> **txn**: [`TxnValueGenerator`](../txn/classes/TxnValueGenerator.md) - -Defined in: [src/value-generators/index.ts:6](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/index.ts#L6) - -## Methods - -### account() - -> **account**(`input`?): `Account` - -Defined in: [src/value-generators/avm.ts:95](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L95) - -Generates a random account with the specified context data. - -#### Parameters - -##### input? - -`AccountContextData` - -The context data for the account. - -#### Returns - -`Account` - -- A random account. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`account`](../avm/classes/AvmValueGenerator.md#account) - -*** - -### application() - -> **application**(`input`?): `Application` - -Defined in: [src/value-generators/avm.ts:153](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L153) - -Generates a random application with the specified context data. - -#### Parameters - -##### input? - -`ApplicationContextData` - -The context data for the application. - -#### Returns - -`Application` - -- A random application. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`application`](../avm/classes/AvmValueGenerator.md#application) - -*** - -### asset() - -> **asset**(`input`?): `Asset` - -Defined in: [src/value-generators/avm.ts:133](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L133) - -Generates a random asset with the specified context data. - -#### Parameters - -##### input? - -`AssetContextData` - -The context data for the asset. - -#### Returns - -`Asset` - -- A random asset. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`asset`](../avm/classes/AvmValueGenerator.md#asset) - -*** - -### biguint() - -> **biguint**(`minValue`?): `biguint` - -Defined in: [src/value-generators/avm.ts:58](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L58) - -Generates a random biguint value within the specified range. - -#### Parameters - -##### minValue? - -`StubBigUintCompat` = `0n` - -The minimum value (inclusive). - -#### Returns - -`biguint` - -- A random biguint value. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`biguint`](../avm/classes/AvmValueGenerator.md#biguint) - -*** - -### bytes() - -> **bytes**(`length`?): `bytes` - -Defined in: [src/value-generators/avm.ts:72](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L72) - -Generates a random bytes of the specified length. - -#### Parameters - -##### length? - -`number` = `MAX_BYTES_SIZE` - -The length of the bytes. - -#### Returns - -`bytes` - -- A random bytes. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`bytes`](../avm/classes/AvmValueGenerator.md#bytes) - -*** - -### string() - -> **string**(`length`?): `string` - -Defined in: [src/value-generators/avm.ts:81](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L81) - -Generates a random string of the specified length. - -#### Parameters - -##### length? - -`number` = `11` - -The length of the string. - -#### Returns - -`string` - -- A random string. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`string`](../avm/classes/AvmValueGenerator.md#string) - -*** - -### uint64() - -> **uint64**(`minValue`?, `maxValue`?): `uint64` - -Defined in: [src/value-generators/avm.ts:38](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/avm.ts#L38) - -Generates a random uint64 value within the specified range. - -#### Parameters - -##### minValue? - -`StubUint64Compat` = `0n` - -The minimum value (inclusive). - -##### maxValue? - -`StubUint64Compat` = `MAX_UINT64` - -The maximum value (inclusive). - -#### Returns - -`uint64` - -- A random uint64 value. - -#### Inherited from - -[`AvmValueGenerator`](../avm/classes/AvmValueGenerator.md).[`uint64`](../avm/classes/AvmValueGenerator.md#uint64) diff --git a/docs/code/value-generators/txn/README.md b/docs/code/value-generators/txn/README.md deleted file mode 100644 index bf67a30..0000000 --- a/docs/code/value-generators/txn/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../README.md) / value-generators/txn - -# value-generators/txn - -## Classes - -- [TxnValueGenerator](classes/TxnValueGenerator.md) diff --git a/docs/code/value-generators/txn/classes/TxnValueGenerator.md b/docs/code/value-generators/txn/classes/TxnValueGenerator.md deleted file mode 100644 index b9dcf1a..0000000 --- a/docs/code/value-generators/txn/classes/TxnValueGenerator.md +++ /dev/null @@ -1,163 +0,0 @@ -[**@algorandfoundation/algorand-typescript-testing**](../../../README.md) - -*** - -[@algorandfoundation/algorand-typescript-testing](../../../README.md) / [value-generators/txn](../README.md) / TxnValueGenerator - -# Class: TxnValueGenerator - -Defined in: [src/value-generators/txn.ts:16](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L16) - -## Constructors - -### Constructor - -> **new TxnValueGenerator**(): `TxnValueGenerator` - -#### Returns - -`TxnValueGenerator` - -## Methods - -### applicationCall() - -> **applicationCall**(`fields`?): `ApplicationCallTransaction` - -Defined in: [src/value-generators/txn.ts:22](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L22) - -Generates a random application call transaction with the specified fields. - -#### Parameters - -##### fields? - -`Partial`\<`Omit`\<`ApplicationCallTransactionFields`, `"appId"`\> & `object`\> - -The fields for the application call transaction where `appId` value can be instance of Application or BaseContract. - -#### Returns - -`ApplicationCallTransaction` - -- A random application call transaction. - -*** - -### assetConfig() - -> **assetConfig**(`fields`?): `AssetConfigTransaction` - -Defined in: [src/value-generators/txn.ts:65](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L65) - -Generates a random asset configuration transaction with the specified fields. - -#### Parameters - -##### fields? - -`Partial`\<`Mutable`\<`Pick`\<`AssetConfigTxn`, keyof `AssetConfigTxn`\>\>\> - -The fields for the asset configuration transaction. - -#### Returns - -`AssetConfigTransaction` - -- A random asset configuration transaction. - -*** - -### assetFreeze() - -> **assetFreeze**(`fields`?): `AssetFreezeTransaction` - -Defined in: [src/value-generators/txn.ts:83](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L83) - -Generates a random asset freeze transaction with the specified fields. - -#### Parameters - -##### fields? - -`Partial`\<`Mutable`\<`Pick`\<`AssetFreezeTxn`, keyof `AssetFreezeTxn`\>\>\> - -The fields for the asset freeze transaction. - -#### Returns - -`AssetFreezeTransaction` - -- A random asset freeze transaction. - -*** - -### assetTransfer() - -> **assetTransfer**(`fields`?): `AssetTransferTransaction` - -Defined in: [src/value-generators/txn.ts:74](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L74) - -Generates a random asset transfer transaction with the specified fields. - -#### Parameters - -##### fields? - -`Partial`\<`Mutable`\<`Pick`\<`AssetTransferTxn`, keyof `AssetTransferTxn`\>\>\> - -The fields for the asset transfer transaction. - -#### Returns - -`AssetTransferTransaction` - -- A random asset transfer transaction. - -*** - -### keyRegistration() - -> **keyRegistration**(`fields`?): `KeyRegistrationTransaction` - -Defined in: [src/value-generators/txn.ts:56](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L56) - -Generates a random key registration transaction with the specified fields. - -#### Parameters - -##### fields? - -`Partial`\<`Mutable`\<`Pick`\<`KeyRegistrationTxn`, keyof `KeyRegistrationTxn`\>\>\> - -The fields for the key registration transaction. - -#### Returns - -`KeyRegistrationTransaction` - -- A random key registration transaction. - -*** - -### payment() - -> **payment**(`fields`?): `PaymentTransaction` - -Defined in: [src/value-generators/txn.ts:47](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/src/value-generators/txn.ts#L47) - -Generates a random payment transaction with the specified fields. - -#### Parameters - -##### fields? - -`Partial`\<`Mutable`\<`Pick`\<`PaymentTxn`, keyof `PaymentTxn`\>\>\> - -The fields for the payment transaction. - -#### Returns - -`PaymentTransaction` - -- A random payment transaction. diff --git a/docs/coverage.md b/docs/coverage.md index c8a29cb..0384844 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -1,6 +1,10 @@ +--- +title: Coverage +--- + # Coverage -See which `algorand-typescript` stubs are implemented by the `algorand-typescript-testing` library. See the [Concepts](testing-guide/concepts.md#types-of-algorand-typescript-stub-implementations) section for more details on the implementation categories. Refer to the [`algorand-typescript` stubs API](api.md) for the full list of the stubs for which the `algorand-typescript-testing` library provides implementations referenced in the table below. +See which `algorand-typescript` stubs are implemented by the `algorand-typescript-testing` library. See the [Concepts](tg-concepts.md#types-of-algorand-typescript-stub-implementations) section for more details on the implementation categories. Refer to the [`algorand-typescript` stubs API](api.md) for the full list of the stubs for which the `algorand-typescript-testing` library provides implementations referenced in the table below. | Name | Implementation type | | ---------------------------- | ------------------- | diff --git a/docs/examples.md b/docs/examples.md index 84bbe69..7cbb0b9 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -1,3 +1,7 @@ +--- +title: Examples +--- + # Examples Below is a showcase of various examples of unit testing real and sample Algorand Python smart contracts using `algorand-typescript-testing`. diff --git a/docs/faq.md b/docs/faq.md index f93119a..5275425 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,8 +1,12 @@ +--- +title: FAQ +--- + # FAQ ## What is a Test Context? -A Test Context is a context manager that provides a simulated Algorand environment for testing TypeScript smart contracts. It allows developers to create and manipulate a virtual Algorand ecosystem for testing purposes. For more details, see the [Test Context section](testing-guide/concepts.md#test-context) in our documentation. +A Test Context is a context manager that provides a simulated Algorand environment for testing TypeScript smart contracts. It allows developers to create and manipulate a virtual Algorand ecosystem for testing purposes. For more details, see the [Test Context section](tg-concepts.md#test-context) in our documentation. ## What is the Algorand Virtual Machine (AVM)? @@ -14,7 +18,7 @@ Operational Codes, or opcodes, are AVM instructions that are executed directly b ## What are Value Generators? -Value Generators are helper methods that generate randomized values for testing when the specific value of the tested type is not important. In the context of Algorand TypeScript testing, these are represented by property on the context manager, accessed via `any.*` (`any.txn.*`, or `any.arc4.*`. in the case of ARC 4 types). To understand how to use Value Generators effectively, check out our [Value Generators section](testing-guide/concepts.md#value-generators) in the documentation. +Value Generators are helper methods that generate randomized values for testing when the specific value of the tested type is not important. In the context of Algorand TypeScript testing, these are represented by property on the context manager, accessed via `any.*` (`any.txn.*`, or `any.arc4.*`. in the case of ARC 4 types). To understand how to use Value Generators effectively, check out our [Value Generators section](tg-concepts.md#value-generators) in the documentation. ## What are the limitations of the Algorand TypeScript Testing framework? @@ -52,7 +56,7 @@ While this framework is useful for unit testing and local development, it should Yes, the `algokit-typescript-template`, accessible via `algokit init`, provides a working example of how to structure `algorand-typecript-testing` along with regular integration tests against localnet. -```{hint} +``` An `algokit-typescript-template` accessible via `algokit init -t typescript`, provides a comprehensive and customizable working example of how to structure `algorand-typescript-testing` along with regular integration tests against localnet. ``` diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000..3e3d7c6 --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,293 @@ +[![docs-repository](https://img.shields.io/badge/url-repository-74dfdc?logo=github&style=flat.svg)](https://github.com/algorandfoundation/algorand-typescript-testing/) +[![learn-AlgoKit](https://img.shields.io/badge/learn-AlgoKit-74dfdc?logo=algorand&mac=flat.svg)](https://developer.algorand.org/algokit/) +[![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) +[![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/) + +`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 behaviors without requiring a network connection, offering fast and reliable testing capabilities with a familiar TypeScript interface. + +The `algorand-typescript-testing` package provides: + +- A simple interface for fast and reliable unit testing +- An offline testing environment that simulates core AVM functionality +- A familiar TypeScript experience, compatible with testing frameworks like [vitest](https://vitest.dev/), and [jest](https://jestjs.io/) + +## Quick Start + +`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. + +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. + +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. + +> **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. + +### Prerequisites + +- Python 3.12 or later +- [Algorand Python](https://github.com/algorandfoundation/puya) +- Node.js 20.x or later +- [Algorand TypeScript](https://github.com/algorandfoundation/puya-ts) + +### Installation + +`algorand-typescript-testing` is distributed via [npm](https://www.npmjs.com/package/@algorandfoundation/algorand-typescript-testing/). Install the package using `npm`: + +```bash +npm i @algorandfoundation/algorand-typescript-testing +``` + +### Testing your first contract + +Let's write a simple contract and test it using the `algorand-typescript-testing` framework. + +#### Simulating AVM + +`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. + +The transformer replicates AVM behavior, 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. + +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`. + +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. + +#### Configuring vitest + +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. + +```typescript +import typescript from '@rollup/plugin-typescript' +import { defineConfig } from 'vitest/config' +import { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer' + +export default defineConfig({ + esbuild: {}, + test: { + setupFiles: 'vitest.setup.ts', + }, + plugins: [ + typescript({ + transformers: { + before: [puyaTsTransformer], + }, + }), + ], +}) +``` + +`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`. + +```typescript +import { beforeAll, expect } from 'vitest' +import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing' + +beforeAll(() => { + addEqualityTesters({ expect }) +}) +``` + +#### Configuring jest + +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. + +```typescript +import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest' + +const presetConfig = createDefaultEsmPreset({}) +const jestConfig: JestConfigWithTsJest = { + ...presetConfig, + testMatch: ['**/*.algo.test.ts'], + setupFilesAfterEnv: ['/jest.setup.ts'], + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + astTransformers: { + before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'], + }, + }, + ], + }, + extensionsToTreatAsEsm: ['.ts'], +} +export default jestConfig +``` + +`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`. + +```typescript +import { beforeAll, expect } from '@jest/globals' +import { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing' + +beforeAll(() => { + addEqualityTesters({ expect }) +}) +``` + +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. + +```json +{ + "name": "puya-ts-demo", + "scripts": { + "test:jest": "tsc && node --experimental-vm-modules --experimental-require-module node_modules/jest/bin/jest" + }, + "engines": { + "node": ">=20.17" + } +} +``` + +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. + +1. Place the file in `\patches` folder. +1. Install [patch-package](https://www.npmjs.com/package/patch-package) package as a dev dependency. +1. Add `"postinstall": "patch-package",` script in `package.json` file. + The patch will then be applied with every `npm install` call. + +```patch +diff --git a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js +index 5198f8f..addb47c 100644 +--- a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js ++++ b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js +@@ -234,7 +234,7 @@ var TsCompiler = /** @class */ (function () { + var _a; + // Initialize memory cache for typescript compiler + this._parsedTsConfig.fileNames +- .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName) && !_this.configSet.isTestFile(fileName); }) ++ .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName); }) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + .forEach(function (fileName) { return _this._fileVersionCache.set(fileName, 0); }); + /* istanbul ignore next */ + +``` + +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'`. + +#### Contract Definition + +```typescript +import { arc4, assert, Bytes, GlobalState, gtxn, LocalState, op, Txn, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' + +export default class VotingContract extends arc4.Contract { + topic = GlobalState({ initialValue: 'default_topic', key: Bytes('topic') }) + votes = GlobalState({ initialValue: Uint64(0), key: Bytes('votes') }) + voted = LocalState({ key: Bytes('voted') }) + + @arc4.abimethod() + public setTopic(topic: string): void { + this.topic.value = topic + } + @arc4.abimethod() + public vote(pay: gtxn.PaymentTxn): boolean { + assert(op.Global.groupSize === 2, 'Expected 2 transactions') + assert(pay.amount === 10_000, 'Incorrect payment amount') + assert(pay.sender === Txn.sender, 'Payment sender must match transaction sender') + + if (this.voted(Txn.sender).hasValue) { + return false // Already voted + } + + this.votes.value = this.votes.value + 1 + this.voted(Txn.sender).value = 1 + return true + } + + @arc4.abimethod({ readonly: true }) + public getVotes(): uint64 { + return this.votes.value + } + + public clearStateProgram(): boolean { + return true + } +} +``` + +#### Test Definition + +```typescript +import { Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, test } from 'vitest' +import VotingContract from './contract.algo' + +describe('Voting contract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + + test('vote function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + const voter = ctx.defaultSender + const payment = ctx.any.txn.payment({ + sender: voter, + amount: 10_000, + }) + + const result = contract.vote(payment) + expect(result).toEqual(true) + expect(contract.votes.value).toEqual(1) + expect(contract.voted(voter).value).toEqual(1) + }) + + test('setTopic function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + const newTopic = ctx.any.string(10) + contract.setTopic(newTopic) + expect(contract.topic.value).toEqual(newTopic) + }) + + test('getVotes function', () => { + // Initialize the contract within the testing context + const contract = ctx.contract.create(VotingContract) + + contract.votes.value = 5 + const votes = contract.getVotes() + expect(votes).toEqual(5) + }) +}) +``` + +This example demonstrates key aspects of testing with `algorand-typescript-testing` for ARC4-based contracts: + +1. ARC4 Contract Features: + + - Use of `arc4.Contract` as the base class for the contract. + - ABI methods defined using the `@arc4.abimethod` decorator. + - Readonly method annotation with `@arc4.abimethod({readonly: true})`. + +2. Testing ARC4 Contracts: + + - Creation of an `arc4.Contract` instance within the test context. + - Use of `ctx.any` for generating random test data. + - Direct invocation of ABI methods on the contract instance. + +3. Transaction Handling: + + - Use of `ctx.any.txn` to create test transactions. + - Passing transaction objects as parameters to contract methods. + +4. State Verification: + - Checking global and local state changes after method execution. + - Verifying return values from ABI methods. + +> **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. + +### Next steps + +To dig deeper into the capabilities of `algorand-typescript-testing`, continue with the following sections. + +#### Contents + +- [Testing Guide](./testing-guide.md) +- [Examples](./examples.md) +- [Coverage](./coverage.md) +- [FQA](./faq.md) +- [API Reference](./api.md) +- [Algorand TypeScript](./algots.md) diff --git a/docs/testing-guide/index.md b/docs/testing-guide.md similarity index 77% rename from docs/testing-guide/index.md rename to docs/testing-guide.md index e004e52..a2e52bf 100644 --- a/docs/testing-guide/index.md +++ b/docs/testing-guide.md @@ -1,8 +1,22 @@ +--- +title: Algorand TypeScript Testing Guide +children: + - ./tg-concepts.md + - ./tg-application-spy.md + - ./tg-avm-types.md + - ./tg-arc4-types.md + - ./tg-transactions.md + - ./tg-contract-testing.md + - ./tg-signature-testing.md + - ./tg-state-management.md + - ./tg-opcodes.md +--- + # Testing Guide The Algorand TypeScript Testing framework provides powerful tools for testing Algorand TypeScript smart contracts within a Node.js environment. This guide covers the main features and concepts of the framework, helping you write effective tests for your Algorand applications. -```{note} +``` For all code examples in the _Testing Guide_ section, assume `context` is an instance of `TestExecutionContext` obtained using the initialising an instance of `TestExecutionContext` class. All subsequent code is executed within this context. ``` @@ -31,11 +45,11 @@ The framework is designed to work seamlessly with Algorand TypeScript smart cont ## Table of Contents -- [Concepts](./concepts.md) -- [AVM Types](./avm-types.md) -- [ARC4 Types](./arc4-types.md) -- [Transactions](./transactions.md) -- [Smart Contract Testing](./contract-testing.md) -- [Smart Signature Testing](./signature-testing.md) -- [State Management](./state-management.md) -- [AVM Opcodes](./opcodes.md) +- [Concepts](./tg-concepts.md) +- [AVM Types](./tg-avm-types.md) +- [ARC4 Types](./tg-arc4-types.md) +- [Transactions](./tg-transactions.md) +- [Smart Contract Testing](./tg-contract-testing.md) +- [Smart Signature Testing](./tg-signature-testing.md) +- [State Management](./tg-state-management.md) +- [AVM Opcodes](./tg-opcodes.md) diff --git a/docs/testing-guide/application-spy.md b/docs/tg-application-spy.md similarity index 99% rename from docs/testing-guide/application-spy.md rename to docs/tg-application-spy.md index e67bd89..462ba22 100644 --- a/docs/testing-guide/application-spy.md +++ b/docs/tg-application-spy.md @@ -1,3 +1,7 @@ +--- +title: Application Spy +--- + # ApplicationSpy The `ApplicationSpy` class provides a way to mock making method calls for from within contracts. This is particularly useful when testing contracts that deploy and interact with other contracts in a type safe manner. It can be used with all the approaches for making method calls supported by `algorand-typescript`. diff --git a/docs/testing-guide/arc4-types.md b/docs/tg-arc4-types.md similarity index 98% rename from docs/testing-guide/arc4-types.md rename to docs/tg-arc4-types.md index d339734..b0429a5 100644 --- a/docs/testing-guide/arc4-types.md +++ b/docs/tg-arc4-types.md @@ -1,12 +1,16 @@ +--- +title: ARC4 Types +--- + # ARC4 Types These types are available under the `arc4` namespace. Refer to the [ARC4 specification](https://arc.algorand.foundation/ARCs/arc-0004) for more details on the spec. -```{hint} +``` Test execution context provides _value generators_ for ARC4 types. To access their _value generators_, use `{context_instance}.any.arc4` property. See more examples below. ``` -```{note} +``` For all `arc4` types with and without respective _value generator_, instantiation can be performed directly. If you have a suggestion for a new _value generator_ implementation, please open an issue in the [`algorand-typescript-testing`](https://github.com/algorandfoundation/algorand-typescript-testing) repository or contribute by following the [contribution guide](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/CONTRIBUTING.md). ``` diff --git a/docs/testing-guide/avm-types.md b/docs/tg-avm-types.md similarity index 99% rename from docs/testing-guide/avm-types.md rename to docs/tg-avm-types.md index 53753c9..b65cea6 100644 --- a/docs/testing-guide/avm-types.md +++ b/docs/tg-avm-types.md @@ -1,8 +1,12 @@ +--- +title: AVM Types +--- + # AVM Types These types are available directly under the `algorand-typescript` namespace. They represent the basic AVM primitive types and can be instantiated directly or via _value generators_: -```{note} +``` For 'primitive `algorand-typescript` types such as `Account`, `Application`, `Asset`, `uint64`, `biguint`, `bytes`, `string` with and without respective _value generator_, instantiation can be performed directly. If you have a suggestion for a new _value generator_ implementation, please open an issue in the [`algorand-typescript-testing`](https://github.com/algorandfoundation/algorand-typescript-testing) repository or contribute by following the [contribution guide](https://github.com/algorandfoundation/algorand-typescript-testing/blob/main/CONTRIBUTING.md). ``` @@ -119,7 +123,7 @@ const account = algots.Account(rawAddress) // zero address by default const randomAccount = ctx.any.account({ address: rawAddress, // Optional: Specify a custom address, defaults to a random address optedAssetBalances: new Map([]), // Optional: Specify opted asset balances as dict of assets to balance - optedApplications: [], // Optional: Specify opted apps as sequence of algopy.Application objects + optedApplications: [], // Optional: Specify opted apps as sequence of Application objects totalAppsCreated: 0, // Optional: Specify the total number of created applications totalAppsOptedIn: 0, // Optional: Specify the total number of applications opted into totalAssets: 0, // Optional: Specify the total number of assets diff --git a/docs/testing-guide/concepts.md b/docs/tg-concepts.md similarity index 77% rename from docs/testing-guide/concepts.md rename to docs/tg-concepts.md index c892fea..fc322fa 100644 --- a/docs/testing-guide/concepts.md +++ b/docs/tg-concepts.md @@ -1,10 +1,14 @@ +--- +title: Concepts +--- + # Concepts The following sections provide an overview of key concepts and features in the Algorand TypeScript Testing framework. ## Test Context -The main abstraction for interacting with the testing framework is the [`TestExecutionContext`](../api.md#contexts). It creates an emulated Algorand environment that closely mimics AVM behavior relevant to unit testing the contracts and provides a TypeScript interface for interacting with the emulated environment. +The main abstraction for interacting with the testing framework is the [`TestExecutionContext`](../classes/index.TestExecutionContext.html). It creates an emulated Algorand environment that closely mimics AVM behavior relevant to unit testing the contracts and provides a TypeScript interface for interacting with the emulated environment. ```typescript import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' @@ -29,14 +33,16 @@ The context manager interface exposes four main properties: 1. `contract`: An instance of `ContractContext` for creating instances of Contract under test and register them with the test execution context. 1. `ledger`: An instance of `LedgerContext` for interacting with and querying the emulated Algorand ledger state. 1. `txn`: An instance of `TransactionContext` for creating and managing transaction groups, submitting transactions, and accessing transaction results. -1. `any`: An instance of `AlgopyValueGenerator` for generating randomized test data. +1. `any`: An instance of `ValueGenerator` for generating randomized test data. For detailed method signatures, parameters, and return types, refer to the following API sections: -- [`ContractContext`](../code/subcontexts/contract-context/classes/ContractContext.md) -- [`LedgerContext`](../code/subcontexts/ledger-context/classes/LedgerContext.md) -- [`TransactionContext`](../code/subcontexts/transaction-context/classes/TransactionContext.md) -- [`AvmValueGenerator`, `TxnValueGenerator`, `Arc4ValueGenerator`](../api.md) +- [`ContractContext`](../classes/index._internal_.ContractContext.html) +- [`LedgerContext`](../classes/index._internal_.LedgerContext.html) +- [`TransactionContext`](../classes/index._internal_.TransactionContext.html) +- [`AvmValueGenerator`, `TxnValueGenerator`, `Arc4ValueGenerator`](../classes/value-generators.ValueGenerator.html) + +### Value generators The `any` property provides access to different value generators: @@ -46,7 +52,7 @@ The `any` property provides access to different value generators: These generators allow creation of constrained random values for various AVM entities (accounts, assets, applications, etc.) when specific values are not required. -```{hint} +``` Value generators are powerful tools for generating test data for specified AVM types. They allow further constraints on random value generation via arguments, making it easier to generate test data when exact values are not necessary. When used with the 'Arrange, Act, Assert' pattern, value generators can be especially useful in setting up clear and concise test data in arrange steps. @@ -55,7 +61,7 @@ When used with the 'Arrange, Act, Assert' pattern, value generators can be espec ## Types of `algorand-typescript` stub implementations -As explained in the [introduction](index.md), `algorand-typescript-testing` _injects_ test implementations for stubs available in the `algorand-typescript` package. However, not all of the stubs are implemented in the same manner: +As explained in the [introduction](testing-guide.md), `algorand-typescript-testing` _injects_ test implementations for stubs available in the `algorand-typescript` package. However, not all of the stubs are implemented in the same manner: 1. **Native**: Fully matches AVM computation in Python. For example, `op.sha256` and other cryptographic operations behave identically in AVM and unit tests. This implies that the majority of opcodes that are 'pure' functions in AVM also have a native TypeScript implementation provided by this package. These abstractions and opcodes can be used within and outside of the testing context. @@ -63,4 +69,4 @@ As explained in the [introduction](index.md), `algorand-typescript-testing` _inj 3. **Mockable**: Not implemented, but can be mocked or patched. For example, `op.onlineStake` can be mocked to return specific values or behaviors; otherwise, it raises a `NotImplementedError`. This category covers cases where native or emulated implementation in a unit test context is impractical or overly complex. -For a full list of all public `algorand-typescript` types and their corresponding implementation category, refer to the [Coverage](../coverage.md) section. +For a full list of all public `algorand-typescript` types and their corresponding implementation category, refer to the [Coverage](./coverage.md) section. diff --git a/docs/testing-guide/contract-testing.md b/docs/tg-contract-testing.md similarity index 96% rename from docs/testing-guide/contract-testing.md rename to docs/tg-contract-testing.md index 5303a72..43c399d 100644 --- a/docs/testing-guide/contract-testing.md +++ b/docs/tg-contract-testing.md @@ -1,8 +1,12 @@ +--- +title: Smart Contract Testing +--- + # Smart Contract Testing This guide provides an overview of how to test smart contracts using the [Algorand Typescript Testing package](https://www.npmjs.com/package/@algorandfoundation/algorand-typescript-testing). We will cover the basics of testing `arc4.Contract` and `BaseContract` classes, focusing on `abimethod` and `baremethod` decorators. -```{note} +``` The code snippets showcasing the contract testing capabilities are using [vitest](https://vitest.dev/) as the test framework. However, note that the `algorand-typescript-testing` package can be used with any other test framework that supports TypeScript. `vitest` is used for demonstration purposes in this documentation. ``` @@ -18,7 +22,7 @@ const ctx = new TestExecutionContext() Subclasses of `arc4.Contract` are **required** to be instantiated with an active test context. As part of instantiation, the test context will automatically create a matching `Application` object instance. -Within the class implementation, methods decorated with `arc4.abimethod` and `arc4.baremethod` will automatically assemble an `gtxn.ApplicationCallTxn` transaction to emulate the AVM application call. This behavior can be overriden by setting the transaction group manually as part of test setup, this is done via implicit invocation of `ctx.any.txn.applicationCall` _value generator_ (refer to [APIs](../apis.md) for more details). +Within the class implementation, methods decorated with `arc4.abimethod` and `arc4.baremethod` will automatically assemble an `gtxn.ApplicationCallTxn` transaction to emulate the AVM application call. This behavior can be overriden by setting the transaction group manually as part of test setup, this is done via implicit invocation of `ctx.any.txn.applicationCall` _value generator_ (refer to [APIs](../modules/index.html) for more details). ```ts class SimpleVotingContract extends arc4.Contract { @@ -71,7 +75,7 @@ expect(contract.topic.value).toEqual(initialTopic) expect(contract.votes.value).toEqual(Uint64(0)) // Act - Vote -// The method `.vote()` is decorated with `algopy.arc4.abimethod`, which means it will assemble a transaction to emulate the AVM application call +// The method `.vote()` is decorated with `arc4.abimethod`, which means it will assemble a transaction to emulate the AVM application call const result = contract.vote() // Assert - you can access the corresponding auto generated application call transaction via test context @@ -98,7 +102,7 @@ const votes = contract.getVotes() expect(votes).toEqual(0) ``` -For more examples of tests using `arc4.Contract`, see the [examples](../examples.md) section. +For more examples of tests using `arc4.Contract`, see the [examples](./examples.md) section. ## `BaseContract`` diff --git a/docs/testing-guide/opcodes.md b/docs/tg-opcodes.md similarity index 97% rename from docs/testing-guide/opcodes.md rename to docs/tg-opcodes.md index 9ccb9b5..8eec5fd 100644 --- a/docs/testing-guide/opcodes.md +++ b/docs/tg-opcodes.md @@ -1,3 +1,7 @@ +--- +title: AVM Opcodes +--- + # AVM Opcodes The [coverage](coverage.md) file provides a comprehensive list of all opcodes and their respective types, categorized as _Mockable_, _Emulated_, or _Native_ within the `algorand-typescript-testing` package. This section highlights a **subset** of opcodes and types that typically require interaction with the test execution context. @@ -66,13 +70,13 @@ const isBitSet = op.getBit(value, 3) const newValue = op.setBit(value, 2, 1) ``` -For a comprehensive list of all opcodes and types, refer to the [coverage](../coverage.md) page. +For a comprehensive list of all opcodes and types, refer to the [coverage](./coverage.md) page. ## Emulated Types Requiring Transaction Context These types necessitate interaction with the transaction context: -### algopy.op.Global +### op.Global ```ts import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' @@ -98,7 +102,7 @@ const result = contract.checkGlobals() expect(result).toEqual(101000) ``` -### algopy.op.Txn +### op.Txn ```ts import { op, arc4 } from '@algorandfoundation/algorand-typescript' @@ -122,7 +126,7 @@ ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: customSender })]).exe }) ``` -### algopy.op.AssetHoldingGet +### op.AssetHoldingGet ```ts import { Account, arc4, Asset, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' @@ -147,7 +151,7 @@ const result = contract.checkAssetHolding(account, asset) expect(result).toEqual(5000) ``` -### algopy.op.AppGlobal +### op.AppGlobal ```ts import { arc4, bytes, Bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' @@ -174,7 +178,7 @@ const [storedValue, _] = ctx.ledger.getGlobalState(contract, key) expect(storedValue?.value).toEqual(42) ``` -### algopy.op.Block +### op.Block ```ts import { arc4, bytes, op } from '@algorandfoundation/algorand-typescript' @@ -196,7 +200,7 @@ const seed = contract.getBlockSeed() expect(seed).toEqual(op.itob(123456)) ``` -### algopy.op.AcctParamsGet +### op.AcctParamsGet ```ts import type { Account, uint64 } from '@algorandfoundation/algorand-typescript' @@ -221,7 +225,7 @@ const balance = contract.getAccountBalance(account) expect(balance).toEqual(Uint64(1000000)) ``` -### algopy.op.AppParamsGet +### op.AppParamsGet ```ts import type { Application } from '@algorandfoundation/algorand-typescript' @@ -245,7 +249,7 @@ const creator = contract.getAppCreator(app) expect(creator).toEqual(ctx.defaultSender) ``` -### algopy.op.AssetParamsGet +### op.AssetParamsGet ```ts import type { uint64 } from '@algorandfoundation/algorand-typescript' @@ -269,7 +273,7 @@ const total = contract.getAssetTotal(asset.id) expect(total).toEqual(1000000) ``` -### algopy.op.Box +### op.Box ```ts import type { bytes } from '@algorandfoundation/algorand-typescript' @@ -299,7 +303,7 @@ const storedValue = ctx.ledger.getBox(contract, key) expect(storedValue).toEqual(value) ``` -### algopy.compile_contract +### compile_contract ```ts import { arc4, compile, uint64 } from '@algorandfoundation/algorand-typescript' @@ -329,7 +333,7 @@ expect(result).toBe(4) These opcodes are mockable in `algorand-typescript-testing`, allowing for controlled testing of complex operations. Note that the module being mocked is `@algorandfoundation/algorand-typescript-testing/internal` which holds the stub implementations of `algorand-typescript` functions to be executed in Node.js environment. -### algopy.op.vrf_verify +### op.vrf_verify ```ts import { expect, Mock, test, vi } from 'vitest' @@ -356,7 +360,7 @@ test('mock vrfVerify', () => { }) ``` -### algopy.op.EllipticCurve +### op.EllipticCurve ```ts import { expect, Mock, test, vi } from 'vitest' diff --git a/docs/testing-guide/signature-testing.md b/docs/tg-signature-testing.md similarity index 93% rename from docs/testing-guide/signature-testing.md rename to docs/tg-signature-testing.md index 47cd144..d53d32e 100644 --- a/docs/testing-guide/signature-testing.md +++ b/docs/tg-signature-testing.md @@ -1,3 +1,7 @@ +--- +title: Smart Signature Testing +--- + # Smart Signature Testing Test Algorand smart signatures (LogicSigs) with ease using the Algorand TypeScript Testing framework. @@ -68,7 +72,7 @@ const secret = algots.Bytes('secret') expect(ctx.executeLogicSig(new HashedTimeLockedLogicSig(), secret)) ``` -For more details on available operations, see the [coverage](../coverage.md). +For more details on available operations, see the [coverage](./coverage.md). ```ts // test cleanup diff --git a/docs/testing-guide/state-management.md b/docs/tg-state-management.md similarity index 95% rename from docs/testing-guide/state-management.md rename to docs/tg-state-management.md index e97749f..5d24cfa 100644 --- a/docs/testing-guide/state-management.md +++ b/docs/tg-state-management.md @@ -1,3 +1,7 @@ +--- +title: State Management +--- + # State Management `algorand-typescript-testing` provides tools to test state-related abstractions in Algorand smart contracts. This guide covers global state, local state, boxes, and scratch space management. @@ -98,7 +102,7 @@ const scratchSpace = ctx.txn.lastGroup.getScratchSpace() expect(scratchSpace[1]).toEqual(5) ``` -For more detailed information, explore the example contracts in the `examples/` directory, the [coverage](../coverage.md) page, and the [API documentation](../api.md). +For more detailed information, explore the example contracts in the `examples/` directory, the [coverage](./coverage.md) page, and the [API documentation](../modules/index.html). ```ts // test cleanup diff --git a/docs/testing-guide/transactions.md b/docs/tg-transactions.md similarity index 92% rename from docs/testing-guide/transactions.md rename to docs/tg-transactions.md index 2e79360..ce1a272 100644 --- a/docs/testing-guide/transactions.md +++ b/docs/tg-transactions.md @@ -1,6 +1,10 @@ +--- +title: Transactions +--- + # Transactions -The testing framework follows the Transaction definitions described in [`algorand-typescript` docs](https://github.com/algorandfoundation/puya-ts/blob/main/docs/lg-transactions.md). This section focuses on _value generators_ and interactions with inner transactions, it also explains how the framework identifies _active_ transaction group during contract method/subroutine/logicsig invocation. +The testing framework follows the Transaction definitions described in [`algorand-typescript` docs](https://algorandfoundation.github.io/puya-ts/documents/Algorand_TypeScript_Language_Guide.Types.html#group-transactions). This section focuses on _value generators_ and interactions with inner transactions, it also explains how the framework identifies _active_ transaction group during contract method/subroutine/logicsig invocation. ```ts import * as algots from '@algorandfoundation/algorand-typescript' @@ -12,7 +16,7 @@ const ctx = new TestExecutionContext() ## Group Transactions -Refers to test implementation of transaction stubs available under `algots.gtxn.*` namespace. Available under [`TxnValueGenerator`](../code/value-generators/txn/classes/TxnValueGenerator.md) instance accessible via `ctx.any.txn` property: +Refers to test implementation of transaction stubs available under `algots.gtxn.*` namespace. Available under [`TxnValueGenerator`](../classes/value-generators._internal_.TxnValueGenerator.html) instance accessible via `ctx.any.txn` property: ```ts // Generate a random payment transaction @@ -82,7 +86,7 @@ const assetFreezeTxn = ctx.any.txn.assetFreeze({ When a smart contract instance (application) is interacted with on the Algorand network, it must be performed in relation to a specific transaction or transaction group where one or many transactions are application calls to target smart contract instances. -To emulate this behaviour, the `createScope` context manager is available on [`TransactionContext`](../code/subcontexts/transaction-context/classes/TransactionContext.md) instance that allows setting temporary transaction fields within a specific scope, passing in emulated transaction objects and identifying the active transaction index within the transaction group +To emulate this behaviour, the `createScope` context manager is available on [`TransactionContext`](../classes/index._internal_.TransactionContext.html) instance that allows setting temporary transaction fields within a specific scope, passing in emulated transaction objects and identifying the active transaction index within the transaction group ```ts import { arc4, Txn } from '@algorandfoundation/algorand-typescript' @@ -408,9 +412,9 @@ describe('pre compiled typed app calls', () => { ## References -- [API](../api.md) for more details on the test context manager and inner transactions related methods that perform implicit inner transaction type validation. -- [Examples](../examples.md) for more examples of smart contracts and associated tests that interact with inner transactions. -- [ApplicationSpy](./application-spy.md) for detailed explanation on the usage of it +- [API](../modules/index.html) for more details on the test context manager and inner transactions related methods that perform implicit inner transaction type validation. +- [Examples](./examples.md) for more examples of smart contracts and associated tests that interact with inner transactions. +- [ApplicationSpy](./tg-application-spy.md) for detailed explanation on the usage of it ```ts // test cleanup diff --git a/package-lock.json b/package-lock.json index 5b78a10..06f054d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,8 +50,9 @@ "rollup": "^4.38.0", "semantic-release": "^24.2.3", "tsx": "4.19.3", - "typedoc": "^0.28.1", - "typedoc-plugin-markdown": "^4.6.0", + "typedoc": "^0.28.7", + "typedoc-plugin-markdown": "^4.7.1", + "typedoc-plugin-missing-exports": "^4.0.0", "typescript": "^5.8.3", "upath": "^2.0.1", "vitest": "3.2.4" @@ -1278,14 +1279,16 @@ } }, "node_modules/@gerrit0/mini-shiki": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.2.1.tgz", - "integrity": "sha512-HbzRC6MKB6U8kQhczz0APKPIzFHTrcqhaC7es2EXInq1SpjPVnpVSIsBe6hNoLWqqCx1n5VKiPXq6PfXnHZKOQ==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.9.2.tgz", + "integrity": "sha512-Tvsj+AOO4Z8xLRJK900WkyfxHsZQu+Zm1//oT1w443PO6RiYMoq/4NGOhaNuZoUMYsjKIAPVQ6eOFMddj6yphQ==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/engine-oniguruma": "^3.2.1", - "@shikijs/types": "^3.2.1", + "@shikijs/engine-oniguruma": "^3.9.2", + "@shikijs/langs": "^3.9.2", + "@shikijs/themes": "^3.9.2", + "@shikijs/types": "^3.9.2", "@shikijs/vscode-textmate": "^10.0.2" } }, @@ -2557,20 +2560,40 @@ } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.2.1.tgz", - "integrity": "sha512-wZZAkayEn6qu2+YjenEoFqj0OyQI64EWsNR6/71d1EkG4sxEOFooowKivsWPpaWNBu3sxAG+zPz5kzBL/SsreQ==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.9.2.tgz", + "integrity": "sha512-Vn/w5oyQ6TUgTVDIC/BrpXwIlfK6V6kGWDVVz2eRkF2v13YoENUvaNwxMsQU/t6oCuZKzqp9vqtEtEzKl9VegA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.2.1", + "@shikijs/types": "3.9.2", "@shikijs/vscode-textmate": "^10.0.2" } }, + "node_modules/@shikijs/langs": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.9.2.tgz", + "integrity": "sha512-X1Q6wRRQXY7HqAuX3I8WjMscjeGjqXCg/Sve7J2GWFORXkSrXud23UECqTBIdCSNKJioFtmUGJQNKtlMMZMn0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.9.2" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.9.2.tgz", + "integrity": "sha512-6z5lBPBMRfLyyEsgf6uJDHPa6NAGVzFJqH4EAZ+03+7sedYir2yJBRu2uPZOKmj43GyhVHWHvyduLDAwJQfDjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.9.2" + } + }, "node_modules/@shikijs/types": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.2.1.tgz", - "integrity": "sha512-/NTWAk4KE2M8uac0RhOsIhYQf4pdU0OywQuYDGIGAJ6Mjunxl2cGiuLkvu4HLCMn+OTTLRWkjZITp+aYJv60yA==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.9.2.tgz", + "integrity": "sha512-/M5L0Uc2ljyn2jKvj4Yiah7ow/W+DJSglVafvWAJ/b8AZDeeRAdMu3c2riDzB7N42VD+jSnWxeP9AKtd4TfYVw==", "dev": true, "license": "MIT", "dependencies": { @@ -13677,17 +13700,17 @@ } }, "node_modules/typedoc": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.1.tgz", - "integrity": "sha512-Mn2VPNMaxoe/hlBiLriG4U55oyAa3Xo+8HbtEwV7F5WEOPXqtxzGuMZhJYHaqFJpajeQ6ZDUC2c990NAtTbdgw==", + "version": "0.28.10", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.10.tgz", + "integrity": "sha512-zYvpjS2bNJ30SoNYfHSRaFpBMZAsL7uwKbWwqoCNFWjcPnI3e/mPLh2SneH9mX7SJxtDpvDgvd9/iZxGbo7daw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@gerrit0/mini-shiki": "^3.2.1", + "@gerrit0/mini-shiki": "^3.9.0", "lunr": "^2.3.9", "markdown-it": "^14.1.0", "minimatch": "^9.0.5", - "yaml": "^2.7.0 " + "yaml": "^2.8.0" }, "bin": { "typedoc": "bin/typedoc" @@ -13697,13 +13720,13 @@ "pnpm": ">= 10" }, "peerDependencies": { - "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x" } }, "node_modules/typedoc-plugin-markdown": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.6.0.tgz", - "integrity": "sha512-RG90uC1QqGN9kPBjzEckEf0v9yIYlLoNYKm4OqjwEGFJJGOLUDs5pIEQQDR2tAv1RD7D8GUSakRlcHMTipyaOA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.8.1.tgz", + "integrity": "sha512-ug7fc4j0SiJxSwBGLncpSo8tLvrT9VONvPUQqQDTKPxCoFQBADLli832RGPtj6sfSVJebNSrHZQRUdEryYH/7g==", "dev": true, "license": "MIT", "engines": { @@ -13713,6 +13736,16 @@ "typedoc": "0.28.x" } }, + "node_modules/typedoc-plugin-missing-exports": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-4.1.0.tgz", + "integrity": "sha512-p1M5jXnEbQ4qqy0erJz41BBZEDb8XDrbLjndlH4RhYEcymbdQr0xLF6yUw1GWBrhSIfkU98m3BELMAiQh+R1zA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typedoc": "^0.28.1" + } + }, "node_modules/typedoc/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -14434,16 +14467,16 @@ } }, "node_modules/yaml": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", - "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yargs": { diff --git a/package.json b/package.json index 83328e5..f3e4bd3 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,9 @@ "rollup": "^4.38.0", "semantic-release": "^24.2.3", "tsx": "4.19.3", - "typedoc": "^0.28.1", - "typedoc-plugin-markdown": "^4.6.0", + "typedoc": "^0.28.7", + "typedoc-plugin-markdown": "^4.7.1", + "typedoc-plugin-missing-exports": "^4.0.0", "typescript": "^5.8.3", "upath": "^2.0.1", "vitest": "3.2.4" diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index 8790ad2..1747668 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -6,6 +6,7 @@ import type { TypeInfo } from './impl/encoded-types' import { getArc4TypeName } from './impl/encoded-types' import type { DeliberateAny } from './typescript-helpers' +/** @internal */ export interface AbiMetadata { methodName: string name?: string @@ -18,6 +19,7 @@ export interface AbiMetadata { } const metadataStore: WeakMap<{ new (): Contract }, Record> = new WeakMap() +/** @internal */ export const attachAbiMetadata = (contract: { new (): Contract }, methodName: string, metadata: AbiMetadata): void => { if (!metadataStore.has(contract)) { metadataStore.set(contract, {}) @@ -31,6 +33,7 @@ export const attachAbiMetadata = (contract: { new (): Contract }, methodName: st } } +/** @internal */ export const getContractAbiMetadata = (contract: T | { new (): T }): Record => { // Initialize result object to store merged metadata const result: Record = {} @@ -63,11 +66,13 @@ export const getContractAbiMetadata = (contract: T | { new ( return result } +/** @internal */ export const getContractMethodAbiMetadata = (contract: T | { new (): T }, methodName: string): AbiMetadata => { const metadatas = getContractAbiMetadata(contract) return metadatas[methodName] } +/** @internal */ export const getArc4Signature = (metadata: AbiMetadata): string => { if (metadata.methodSignature === undefined) { const argTypes = metadata.argTypes.map((t) => JSON.parse(t) as TypeInfo).map((t) => getArc4TypeName(t, metadata.resourceEncoding, 'in')) @@ -77,6 +82,7 @@ export const getArc4Signature = (metadata: AbiMetadata): string => { return metadata.methodSignature } +/** @internal */ export const getArc4Selector = (metadata: AbiMetadata): Uint8Array => { const hash = js_sha512.sha512_256.array(getArc4Signature(metadata)) return new Uint8Array(hash.slice(0, 4)) diff --git a/src/application-spy.ts b/src/application-spy.ts index 125430e..7086d20 100644 --- a/src/application-spy.ts +++ b/src/application-spy.ts @@ -38,9 +38,9 @@ export class ApplicationSpy { * The `on` property is a proxy that allows you to register callbacks for specific method signatures. * It dynamically creates methods based on the contract's methods. */ - readonly on: _TypedApplicationSpyCallBacks + readonly on: TypedApplicationSpyCallBacks - /* @internal */ + /** @internal */ contract?: TContract | ConstructorFor constructor(contract?: TContract | ConstructorFor) { @@ -48,7 +48,7 @@ export class ApplicationSpy { this.on = this.createOnProxy() } - /* @internal */ + /** @internal */ notify(itxn: ApplicationCallInnerTxnContext) { for (const cb of this.#spyFns) { cb(itxn) @@ -100,9 +100,9 @@ export class ApplicationSpy { } } - private createOnProxy(spy: ApplicationSpy = this): _TypedApplicationSpyCallBacks { - return new Proxy({} as _TypedApplicationSpyCallBacks, { - get(_: _TypedApplicationSpyCallBacks, methodName) { + private createOnProxy(spy: ApplicationSpy = this): TypedApplicationSpyCallBacks { + return new Proxy({} as TypedApplicationSpyCallBacks, { + get(_: TypedApplicationSpyCallBacks, methodName) { const fn = spy._tryGetMethod(methodName) if (fn === undefined) return fn return function (callback: AppSpyCb) { @@ -116,11 +116,11 @@ export class ApplicationSpy { spy.onAbiCall(selector, ocas, callback) } }, - }) as _TypedApplicationSpyCallBacks + }) as TypedApplicationSpyCallBacks } } -type _TypedApplicationSpyCallBacks = { +export type TypedApplicationSpyCallBacks = { [key in keyof TContract as key extends 'approvalProgram' | 'clearStateProgram' ? never : TContract[key] extends AnyFunction diff --git a/src/collections/custom-key-map.ts b/src/collections/custom-key-map.ts index cd09fe9..b2589da 100644 --- a/src/collections/custom-key-map.ts +++ b/src/collections/custom-key-map.ts @@ -1,6 +1,5 @@ -import type { Account } from '@algorandfoundation/algorand-typescript' +import type { Account, BytesCompat, Uint64Compat } from '@algorandfoundation/algorand-typescript' import { InternalError } from '../errors' -import type { StubBytesCompat, StubUint64Compat } from '../impl/primitives' import type { DeliberateAny } from '../typescript-helpers' import { asBytesCls, asUint64Cls } from '../util' @@ -9,6 +8,7 @@ export abstract class CustomKeyMap implements Map { #keySerializer: (key: TKey) => Primitive #map = new Map() + /** @internal */ constructor(keySerializer: (key: TKey) => number | bigint | string) { this.#keySerializer = keySerializer } @@ -66,22 +66,26 @@ export abstract class CustomKeyMap implements Map { } export class AccountMap extends CustomKeyMap { + /** @internal */ constructor() { super(AccountMap.getAddressStrFromAccount) } + /** @internal */ private static getAddressStrFromAccount = (acc: Account) => { return asBytesCls(acc.bytes).valueOf() } } -export class BytesMap extends CustomKeyMap { +export class BytesMap extends CustomKeyMap { + /** @internal */ constructor() { super((bytes) => asBytesCls(bytes).valueOf()) } } -export class Uint64Map extends CustomKeyMap { +export class Uint64Map extends CustomKeyMap { + /** @internal */ constructor() { super((uint64) => asUint64Cls(uint64).valueOf()) } diff --git a/src/constants.ts b/src/constants.ts index 8ade049..1d8d9ec 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,25 +1,45 @@ import { Bytes, FixedBytes } from './impl/primitives' +/** @internal */ export const UINT64_SIZE = 64 +/** @internal */ export const UINT512_SIZE = 512 +/** @internal */ export const MAX_UINT8 = 2 ** 8 - 1 +/** @internal */ export const MAX_UINT16 = 2 ** 16 - 1 +/** @internal */ export const MAX_UINT32 = 2 ** 32 - 1 +/** @internal */ export const MAX_UINT64 = 2n ** 64n - 1n +/** @internal */ export const MAX_UINT128 = 2n ** 128n - 1n +/** @internal */ export const MAX_UINT256 = 2n ** 256n - 1n +/** @internal */ export const MAX_UINT512 = 2n ** 512n - 1n +/** @internal */ export const MAX_BYTES_SIZE = 4096 +/** @internal */ export const MAX_LOG_SIZE = 1024 +/** @internal */ export const MAX_ITEMS_IN_LOG = 32 +/** @internal */ export const MAX_BOX_SIZE = 32768 +/** @internal */ export const BITS_IN_BYTE = 8 +/** @internal */ export const DEFAULT_ACCOUNT_MIN_BALANCE = 100_000 +/** @internal */ export const DEFAULT_MAX_TXN_LIFE = 1_000 +/** @internal */ export const DEFAULT_ASSET_CREATE_MIN_BALANCE = 1000_000 +/** @internal */ export const DEFAULT_ASSET_OPT_IN_MIN_BALANCE = 10_000 -// from python code: list(b"\x85Y\xb5\x14x\xfd\x89\xc1vC\xd0]\x15\xa8\xaek\x10\xabG\xbbm\x8a1\x88\x11V\xe6\xbd;\xae\x95\xd1") +/** @internal + * from python code: list(b"\x85Y\xb5\x14x\xfd\x89\xc1vC\xd0]\x15\xa8\xaek\x10\xabG\xbbm\x8a1\x88\x11V\xe6\xbd;\xae\x95\xd1") + */ export const DEFAULT_GLOBAL_GENESIS_HASH = FixedBytes( 32, new Uint8Array([ @@ -28,37 +48,55 @@ export const DEFAULT_GLOBAL_GENESIS_HASH = FixedBytes( ]), ) -// algorand encoded address of 32 zero bytes +/** @internal + * algorand encoded address of 32 zero bytes + */ export const ZERO_ADDRESS = Bytes.fromBase32('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') -/** +/** @internal "\x09" # pragma version 9 "\x81\x01" # pushint 1 */ export const ALWAYS_APPROVE_TEAL_PROGRAM = Bytes(new Uint8Array([0x09, 0x81, 0x01])) -// bytes: program (logic) data prefix when signing +/** @internal + * bytes: program (logic) data prefix when signing + */ export const LOGIC_DATA_PREFIX = Bytes('ProgData') -//number: minimum transaction fee +/** @internal + * number: minimum transaction fee + */ export const MIN_TXN_FEE = 1000 +/** @internal */ export const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') +/** @internal */ export const UINT64_OVERFLOW_UNDERFLOW_MESSAGE = 'Uint64 overflow or underflow' +/** @internal */ export const BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE = 'BigUint overflow or underflow' +/** @internal */ export const DEFAULT_TEMPLATE_VAR_PREFIX = 'TMPL_' +/** @internal */ export const APP_ID_PREFIX = 'appID' +/** @internal */ export const HASH_BYTES_LENGTH = 32 +/** @internal */ export const ALGORAND_ADDRESS_BYTE_LENGTH = 36 +/** @internal */ export const ALGORAND_CHECKSUM_BYTE_LENGTH = 4 +/** @internal */ export const ALGORAND_ADDRESS_LENGTH = 58 +/** @internal */ export const PROGRAM_TAG = 'Program' +/** @internal */ export const TRANSACTION_GROUP_MAX_SIZE = 16 +/** @internal */ export enum OnApplicationComplete { NoOpOC = 0, OptInOC = 1, @@ -68,6 +106,7 @@ export enum OnApplicationComplete { DeleteApplicationOC = 5, } +/** @internal */ export const ConventionalRouting = { methodNames: { closeOutOfApplication: 'closeOutOfApplication', diff --git a/src/context-helpers/context-manager.ts b/src/context-helpers/context-manager.ts index daa02de..9b81057 100644 --- a/src/context-helpers/context-manager.ts +++ b/src/context-helpers/context-manager.ts @@ -1,5 +1,6 @@ import type { TestExecutionContext } from '../test-execution-context' +/** @internal */ export class ContextManager { private static _instance: TestExecutionContext | undefined diff --git a/src/context-helpers/context-util.ts b/src/context-helpers/context-util.ts index b78836b..57e36b7 100644 --- a/src/context-helpers/context-util.ts +++ b/src/context-helpers/context-util.ts @@ -5,6 +5,7 @@ import { AssertError } from '../errors' import { ApplicationCallTransaction } from '../impl/transactions' import { lazyContext } from './internal-context' +/** @internal */ export const checkRoutingConditions = (appId: uint64, metadata: AbiMetadata) => { const appData = lazyContext.getApplicationData(appId) const isCreating = appData.isCreating diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index b3df401..2777304 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -65,7 +65,7 @@ class InternalContext { } getApplicationData(id: StubUint64Compat | BaseContract): ApplicationData { - const uint64Id = id instanceof BaseContract ? this.ledger.getApplicationForContract(id).id : Uint64Cls.fromCompat(id) + const uint64Id = id instanceof BaseContract ? this.ledger.getApplicationForContract(id).id : Uint64Cls.fromCompat(id).asAlgoTs() const data = this.ledger.applicationDataMap.get(uint64Id) if (!data) { throw new InternalError('Unknown application, check correct testing context is active') @@ -82,4 +82,5 @@ class InternalContext { } } +/** @internal */ export const lazyContext = new InternalContext() diff --git a/src/decode-logs.ts b/src/decode-logs.ts index 6bd0f9b..8ab82ec 100644 --- a/src/decode-logs.ts +++ b/src/decode-logs.ts @@ -4,13 +4,13 @@ import { btoi } from './impl/pure' import { asNumber } from './util' export type LogDecoding = 'i' | 's' | 'b' - export type DecodedLog = T extends 'i' ? bigint : T extends 's' ? string : Uint8Array export type DecodedLogs = { [Index in keyof T]: DecodedLog } & { length: T['length'] } const ABI_RETURN_VALUE_LOG_PREFIX_LENGTH = asNumber(ABI_RETURN_VALUE_LOG_PREFIX.length) +/** @internal */ export function decodeLogs(logs: bytes[], decoding: T): DecodedLogs { return logs.map((log, i) => { const value = log.slice(0, ABI_RETURN_VALUE_LOG_PREFIX_LENGTH).equals(ABI_RETURN_VALUE_LOG_PREFIX) diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index fae3b15..3cbfb54 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -5,6 +5,7 @@ import { getApp } from './app-params' import { Global } from './global' import type { StubUint64Compat } from './primitives' +/** @internal */ export const getAccount = (acct: Account | StubUint64Compat): Account => { const acctId = asMaybeUint64Cls(acct) if (acctId !== undefined) { @@ -14,16 +15,19 @@ export const getAccount = (acct: Account | StubUint64Compat): Account => { return acct as Account } +/** @internal */ export const balance = (a: Account | StubUint64Compat): uint64 => { const acct = getAccount(a) return acct.balance } +/** @internal */ export const minBalance = (a: Account | StubUint64Compat): uint64 => { const acct = getAccount(a) return acct.minBalance } +/** @internal */ export const appOptedIn = (a: Account | StubUint64Compat, b: Application | StubUint64Compat): boolean => { const account = getAccount(a) const app = getApp(b) @@ -34,6 +38,7 @@ export const appOptedIn = (a: Account | StubUint64Compat, b: Application | StubU return account.isOptedIn(app) } +/** @internal */ export const AcctParams: typeof op.AcctParams = { acctBalance(a: Account | StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) diff --git a/src/impl/app-global.ts b/src/impl/app-global.ts index fb75523..67ec19f 100644 --- a/src/impl/app-global.ts +++ b/src/impl/app-global.ts @@ -1,13 +1,14 @@ -import type { Application, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import type { Application, bytes, BytesCompat, op, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asBytes } from '../util' import { getApp } from './app-params' import { toBytes } from './encoded-types' import { Bytes, Uint64, type StubBytesCompat, type StubUint64Compat } from './primitives' +/** @internal */ export const AppGlobal: typeof op.AppGlobal = { delete(a: StubBytesCompat): void { - lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, undefined) + lazyContext.ledger.setGlobalState(lazyContext.activeApplication, asBytes(a), undefined) }, getBytes(a: StubBytesCompat): bytes { return this.getExBytes(0, asBytes(a))[0] @@ -20,7 +21,7 @@ export const AppGlobal: typeof op.AppGlobal = { if (app === undefined) { return [Bytes(), false] } - const [state, exists] = lazyContext.ledger.getGlobalState(app, b) + const [state, exists] = lazyContext.ledger.getGlobalState(app, asBytes(b)) if (!exists) { return [Bytes(), false] } @@ -31,13 +32,13 @@ export const AppGlobal: typeof op.AppGlobal = { if (app === undefined) { return [Uint64(0), false] } - const [state, exists] = lazyContext.ledger.getGlobalState(app, b) + const [state, exists] = lazyContext.ledger.getGlobalState(app, asBytes(b)) if (!exists) { return [Uint64(0), false] } return [state!.value as uint64, exists] }, put(a: StubBytesCompat, b: StubUint64Compat | StubBytesCompat): void { - lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, b) + lazyContext.ledger.setGlobalState(lazyContext.activeApplication, asBytes(a), b as unknown as Uint64Compat | BytesCompat) }, } diff --git a/src/impl/app-local.ts b/src/impl/app-local.ts index 610170e..0f56b05 100644 --- a/src/impl/app-local.ts +++ b/src/impl/app-local.ts @@ -6,11 +6,12 @@ import { getApp } from './app-params' import { toBytes } from './encoded-types' import { Bytes, Uint64, type StubBytesCompat, type StubUint64Compat } from './primitives' +/** @internal */ export const AppLocal: typeof op.AppLocal = { delete: function (a: Account | StubUint64Compat, b: StubBytesCompat): void { const app = lazyContext.activeApplication const account = getAccount(a) - lazyContext.ledger.setLocalState(app, account, b, undefined) + lazyContext.ledger.setLocalState(app, account, asBytes(b), undefined) }, getBytes: function (a: Account | StubUint64Compat, b: StubBytesCompat): bytes { const account = getAccount(a) @@ -26,7 +27,7 @@ export const AppLocal: typeof op.AppLocal = { if (app === undefined || account === undefined) { return [Bytes(), false] } - const [state, exists] = lazyContext.ledger.getLocalState(app, account, c) + const [state, exists] = lazyContext.ledger.getLocalState(app, account, asBytes(c)) if (!exists) { return [Bytes(), false] } @@ -38,7 +39,7 @@ export const AppLocal: typeof op.AppLocal = { if (app === undefined || account === undefined) { return [Uint64(0), false] } - const [state, exists] = lazyContext.ledger.getLocalState(app, account, c) + const [state, exists] = lazyContext.ledger.getLocalState(app, account, asBytes(c)) if (!exists) { return [Uint64(0), false] } @@ -47,6 +48,6 @@ export const AppLocal: typeof op.AppLocal = { put: function (a: Account | StubUint64Compat, b: StubBytesCompat, c: uint64 | bytes): void { const app = lazyContext.activeApplication const account = getAccount(a) - lazyContext.ledger.setLocalState(app, account, b, c) + lazyContext.ledger.setLocalState(app, account, asBytes(b), c) }, } diff --git a/src/impl/app-params.ts b/src/impl/app-params.ts index 8989ee5..03d2350 100644 --- a/src/impl/app-params.ts +++ b/src/impl/app-params.ts @@ -20,6 +20,7 @@ const resolveAppIndex = (appIdOrIndex: StubUint64Compat): uint64 => { return txn.apps(input).id } +/** @internal */ export const getApp = (app: ApplicationType | StubUint64Compat): ApplicationType | undefined => { try { const appId = asMaybeUint64Cls(app) @@ -32,6 +33,7 @@ export const getApp = (app: ApplicationType | StubUint64Compat): ApplicationType } } +/** @internal */ export const AppParams: typeof op.AppParams = { appApprovalProgram(a: ApplicationType | StubUint64Compat): readonly [bytes, boolean] { const app = getApp(a) diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts index 06256bf..634cdd6 100644 --- a/src/impl/asset-holding.ts +++ b/src/impl/asset-holding.ts @@ -20,6 +20,7 @@ const getAssetHolding = (acctOrIndex: Account | StubUint64Compat, assetOrIndex: return holding } +/** @internal */ export const AssetHolding: typeof op.AssetHolding = { assetBalance(a: Account | StubUint64Compat, b: Asset | StubUint64Compat): readonly [uint64, boolean] { const holding = getAssetHolding(a, b) diff --git a/src/impl/asset-params.ts b/src/impl/asset-params.ts index 27f0375..0e2cffc 100644 --- a/src/impl/asset-params.ts +++ b/src/impl/asset-params.ts @@ -13,6 +13,7 @@ const resolveAssetIndex = (assetIdOrIndex: StubUint64Compat): uint64 => { return txn.assets(input).id } +/** @internal */ export const getAsset = (asset: AssetType | StubUint64Compat): AssetType | undefined => { try { const assetId = asMaybeUint64Cls(asset) @@ -25,6 +26,7 @@ export const getAsset = (asset: AssetType | StubUint64Compat): AssetType | undef } } +/** @internal */ export const AssetParams: typeof op.AssetParams = { assetTotal(a: AssetType | StubUint64Compat): readonly [uint64, boolean] { const asset = getAsset(a) diff --git a/src/impl/base-32.ts b/src/impl/base-32.ts index 1d345e7..b98972d 100644 --- a/src/impl/base-32.ts +++ b/src/impl/base-32.ts @@ -2,6 +2,7 @@ const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('') const CHAR_TO_NUM = BASE32_ALPHABET.reduce((acc, cur, index) => ((acc[cur] = index), acc), {} as Record) +/** @internal */ export const base32ToUint8Array = (value: string): Uint8Array => { let allChars = value .split('') @@ -29,6 +30,7 @@ export const base32ToUint8Array = (value: string): Uint8Array => { return new Uint8Array(bytes) } +/** @internal */ export const uint8ArrayToBase32 = (value: Uint8Array): string => { let allBytes = Array.from(value) let base32str = '' diff --git a/src/impl/base-contract.ts b/src/impl/base-contract.ts index b8429a3..8ff2df7 100644 --- a/src/impl/base-contract.ts +++ b/src/impl/base-contract.ts @@ -1,6 +1,7 @@ import type { contract as contractType, uint64 } from '@algorandfoundation/algorand-typescript' import type { ConstructorFor } from '../typescript-helpers' +/** @internal */ export abstract class BaseContract { static isArc4 = false @@ -10,7 +11,9 @@ export abstract class BaseContract { } } +/** @internal */ export const ContractOptionsSymbol = Symbol('ContractOptions') +/** @internal */ export function contract(options: Parameters[0]) { return >(contract: T, ctx: ClassDecoratorContext) => { ctx.addInitializer(function () { diff --git a/src/impl/base.ts b/src/impl/base.ts index fcbf481..6b620fc 100644 --- a/src/impl/base.ts +++ b/src/impl/base.ts @@ -4,16 +4,15 @@ import type { TypeInfo } from '../impl/encoded-types' import type { StubBytesCompat } from './primitives' import { BytesCls, Uint64 } from './primitives' +/** @internal */ export abstract class BytesBackedCls { #value: bytes - // #typeInfo: GenericTypeInfo | undefined get bytes() { return this.#value } constructor(value: bytes, _typeInfo?: TypeInfo) { this.#value = value - // this.#typeInfo = typeInfo } static fromBytes( @@ -25,6 +24,7 @@ export abstract class BytesBackedCls { } } +/** @internal */ export abstract class Uint64BackedCls { #value: uint64 diff --git a/src/impl/block.ts b/src/impl/block.ts index 284be87..06f2e54 100644 --- a/src/impl/block.ts +++ b/src/impl/block.ts @@ -1,7 +1,7 @@ import type { Account as AccountType, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asUint64, getRandomBytes } from '../util' -import { Uint64, type StubUint64Compat } from './primitives' +import { Uint64 } from './primitives' import { Account } from './reference' export class BlockData { @@ -16,6 +16,7 @@ export class BlockData { txnCounter: uint64 proposerPayout: uint64 + /** @internal */ constructor() { this.seed = getRandomBytes(32).asAlgoTs().toFixed({ length: 32 }) this.timestamp = asUint64(Date.now()) @@ -30,11 +31,12 @@ export class BlockData { } } +/** @internal */ export const Block: typeof op.Block = { - blkSeed: function (a: StubUint64Compat): bytes<32> { + blkSeed: function (a: uint64): bytes<32> { return lazyContext.ledger.getBlockData(a).seed }, - blkTimestamp: function (a: StubUint64Compat): uint64 { + blkTimestamp: function (a: uint64): uint64 { return lazyContext.ledger.getBlockData(a).timestamp }, blkProposer: function (a: uint64): AccountType { diff --git a/src/impl/box.ts b/src/impl/box.ts index 440193e..0120fee 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -6,6 +6,7 @@ import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays } from ' import { toBytes } from './encoded-types' import type { StubBytesCompat, StubUint64Compat } from './primitives' +/** @internal */ export const Box: typeof op.Box = { create(a: StubBytesCompat, b: StubUint64Compat): boolean { const name = asBytes(a) diff --git a/src/impl/c2c.ts b/src/impl/c2c.ts index 6a62e5e..293b48a 100644 --- a/src/impl/c2c.ts +++ b/src/impl/c2c.ts @@ -12,6 +12,7 @@ import { ApplicationCallInnerTxnContext } from './inner-transactions' import { methodSelector } from './method-selector' import type { ApplicationData } from './reference' +/** @internal */ export function compileArc4( contract: ConstructorFor, options?: CompileContractOptions, @@ -71,6 +72,7 @@ export function compileArc4( } as unknown as ContractProxy } +/** @internal */ export const invokeAbiCall = (itxnContext: ApplicationCallInnerTxnContext) => { lazyContext.value.notifyApplicationSpies(itxnContext) lazyContext.txn.activeGroup.addInnerTransactionGroup(...(itxnContext.itxns ?? []), itxnContext) @@ -85,6 +87,7 @@ const getCommonApplicationCallFields = (app: ApplicationData | undefined, option localNumBytes: options?.localBytes ?? app?.application.localNumBytes ?? lazyContext.any.uint64(), }) +/** @internal */ export function getApplicationCallInnerTxnContext( method: InstanceMethod, methodArgs: TypedApplicationCallFields, @@ -101,6 +104,7 @@ export function getApplicationCallInnerTxnContext( method: InstanceMethod, methodArgs: TypedApplicationCallFields, diff --git a/src/impl/clone.ts b/src/impl/clone.ts index 7a8a552..c361ac2 100644 --- a/src/impl/clone.ts +++ b/src/impl/clone.ts @@ -1,5 +1,6 @@ import { getEncoder, toBytes } from './encoded-types' +/** @internal */ export function clone(typeInfoString: string, value: T): T { if (value && typeof value === 'object' && 'copy' in value && typeof value.copy === 'function') { return value.copy() as T diff --git a/src/impl/compiled.ts b/src/impl/compiled.ts index 1d4ae2e..b1e175a 100644 --- a/src/impl/compiled.ts +++ b/src/impl/compiled.ts @@ -11,6 +11,7 @@ import { lazyContext } from '../context-helpers/internal-context' import type { ConstructorFor } from '../typescript-helpers' import type { ApplicationData } from './reference' +/** @internal */ export function compile( artefact: ConstructorFor | ConstructorFor, options?: CompileContractOptions | CompileLogicSigOptions, diff --git a/src/impl/contract.ts b/src/impl/contract.ts index e09ff71..9f31783 100644 --- a/src/impl/contract.ts +++ b/src/impl/contract.ts @@ -2,6 +2,7 @@ import type { arc4, OnCompleteActionStr } from '@algorandfoundation/algorand-typ import type { DeliberateAny } from '../typescript-helpers' import { BaseContract } from './base-contract' +/** @internal */ export class Contract extends BaseContract { static isArc4 = true @@ -10,7 +11,9 @@ export class Contract extends BaseContract { } } +/** @internal */ export const Arc4MethodConfigSymbol = Symbol('Arc4MethodConfig') +/** @internal */ export function abimethod(config?: arc4.AbiMethodConfig) { return function ( target: { [Arc4MethodConfigSymbol]: arc4.AbiMethodConfig } & ((this: TContract, ...args: TArgs) => TReturn), @@ -24,6 +27,7 @@ export function abimethod(config?: arc4.AbiMethodCon } } +/** @internal */ export function baremethod(config?: arc4.BareMethodConfig) { return function ( target: { [Arc4MethodConfigSymbol]: arc4.AbiMethodConfig } & ((this: TContract, ...args: TArgs) => TReturn), diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index fc7595d..eb037ce 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -12,6 +12,7 @@ import { asBytes, asBytesCls, asUint8Array, conactUint8Arrays } from '../util' import type { StubBytesCompat, StubUint64Compat } from './primitives' import { Bytes, BytesCls, FixedBytes, Uint64Cls } from './primitives' +/** @internal */ export const sha256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha256.sha256.create().update(bytesA.asUint8Array()).digest() @@ -19,6 +20,7 @@ export const sha256 = (a: StubBytesCompat): bytes<32> => { return hashBytes } +/** @internal */ export const sha3_256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha3.sha3_256.create().update(bytesA.asUint8Array()).digest() @@ -26,6 +28,7 @@ export const sha3_256 = (a: StubBytesCompat): bytes<32> => { return hashBytes } +/** @internal */ export const keccak256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha3.keccak256.create().update(bytesA.asUint8Array()).digest() @@ -33,6 +36,7 @@ export const keccak256 = (a: StubBytesCompat): bytes<32> => { return hashBytes } +/** @internal */ export const sha512_256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha512.sha512_256.create().update(bytesA.asUint8Array()).digest() @@ -40,6 +44,7 @@ export const sha512_256 = (a: StubBytesCompat): bytes<32> => { return hashBytes } +/** @internal */ export const ed25519verifyBare = (a: StubBytesCompat, b: StubBytesCompat, c: StubBytesCompat): boolean => { const bytesA = BytesCls.fromCompat(a) const bytesB = BytesCls.fromCompat(b) @@ -47,6 +52,7 @@ export const ed25519verifyBare = (a: StubBytesCompat, b: StubBytesCompat, c: Stu return nacl.sign.detached.verify(bytesA.asUint8Array(), bytesB.asUint8Array(), bytesC.asUint8Array()) } +/** @internal */ export const ed25519verify = (a: StubBytesCompat, b: StubBytesCompat, c: StubBytesCompat): boolean => { const txn = lazyContext.activeGroup.activeTransaction as gtxn.ApplicationCallTxn const programBytes = asBytesCls(txn.onCompletion == OnCompleteAction.ClearState ? txn.clearStateProgram : txn.approvalProgram) @@ -59,6 +65,7 @@ export const ed25519verify = (a: StubBytesCompat, b: StubBytesCompat, c: StubByt return ed25519verifyBare(data, b, c) } +/** @internal */ export const ecdsaVerify = ( v: Ecdsa, a: StubBytesCompat, @@ -82,6 +89,7 @@ export const ecdsaVerify = ( return keyPair.verify(dataBytes.asUint8Array(), { r: sigRBytes.asUint8Array(), s: sigSBytes.asUint8Array() }) } +/** @internal */ export const ecdsaPkRecover = ( v: Ecdsa, a: StubBytesCompat, @@ -109,6 +117,7 @@ export const ecdsaPkRecover = ( return [FixedBytes(32, x), FixedBytes(32, y)] } +/** @internal */ export const ecdsaPkDecompress = (v: Ecdsa, a: StubBytesCompat): readonly [bytes<32>, bytes<32>] => { const bytesA = BytesCls.fromCompat(a) @@ -121,16 +130,19 @@ export const ecdsaPkDecompress = (v: Ecdsa, a: StubBytesCompat): readonly [bytes return [FixedBytes(32, new Uint8Array(x)), FixedBytes(32, new Uint8Array(y))] } +/** @internal */ export const vrfVerify = (_s: VrfVerify, _a: StubBytesCompat, _b: StubBytesCompat, _c: StubBytesCompat): readonly [bytes<64>, boolean] => { throw new NotImplementedError('vrfVerify') } +/** @internal */ export const EllipticCurve = new Proxy({} as typeof op.EllipticCurve, { get: (_target, prop) => { throw new NotImplementedError(`EllipticCurve.${prop.toString()}`) }, }) +/** @internal */ export const mimc = (_c: MimcConfigurations, _a: StubBytesCompat): bytes => { throw new NotImplementedError('mimc') } diff --git a/src/impl/emit.ts b/src/impl/emit.ts index 5c6930e..c6a4d3e 100644 --- a/src/impl/emit.ts +++ b/src/impl/emit.ts @@ -4,6 +4,7 @@ import { sha512_256 } from './crypto' import { getArc4Encoded, getArc4TypeName } from './encoded-types' import { log } from './log' +/** @internal */ export function emit(typeInfoString: string, event: T | string, ...eventProps: unknown[]) { let eventData let eventName diff --git a/src/impl/encoded-types/array-proxy.ts b/src/impl/encoded-types/array-proxy.ts index 4bcc7d0..1e861b5 100644 --- a/src/impl/encoded-types/array-proxy.ts +++ b/src/impl/encoded-types/array-proxy.ts @@ -2,6 +2,7 @@ import type { Uint64Compat } from '@algorandfoundation/algorand-typescript' import { AvmError } from '../../errors' import { arrayUtil } from '../primitives' +/** @internal */ export const arrayProxyHandler = () => ({ get(target: { items: readonly TItem[] }, prop: PropertyKey) { const idx = prop ? parseInt(prop.toString(), 10) : NaN diff --git a/src/impl/encoded-types/constants.ts b/src/impl/encoded-types/constants.ts index f1ef34b..09c497f 100644 --- a/src/impl/encoded-types/constants.ts +++ b/src/impl/encoded-types/constants.ts @@ -1,4 +1,8 @@ +/** @internal */ export const ABI_LENGTH_SIZE = 2 +/** @internal */ export const TRUE_BIGINT_VALUE = 128n +/** @internal */ export const FALSE_BIGINT_VALUE = 0n +/** @internal */ export const IS_INITIALISING_FROM_BYTES_SYMBOL = Symbol('IsInitialisingFromBytes') diff --git a/src/impl/encoded-types/encoded-types.ts b/src/impl/encoded-types/encoded-types.ts index c862377..9de0aff 100644 --- a/src/impl/encoded-types/encoded-types.ts +++ b/src/impl/encoded-types/encoded-types.ts @@ -79,6 +79,7 @@ import type { } from './types' import { getMaxLengthOfStaticContentType } from './utils' +/** @internal */ export class Uint extends _Uint { private value: Uint8Array private bitSize: N @@ -130,6 +131,7 @@ export class Uint extends _Uint { } } +/** @internal */ export class UFixed extends _UFixed { private value: Uint8Array private bitSize: N @@ -190,6 +192,7 @@ export class UFixed extends _UFixed { } } +/** @internal */ export class Byte extends _Byte { typeInfo: TypeInfo private value: Uint<8> @@ -227,6 +230,7 @@ export class Byte extends _Byte { } } +/** @internal */ export class Str extends _Str { typeInfo: TypeInfo private value: Uint8Array @@ -265,6 +269,7 @@ export class Str extends _Str { } } +/** @internal */ export class Bool extends _Bool { private value: Uint8Array typeInfo: TypeInfo @@ -302,6 +307,7 @@ export class Bool extends _Bool { } } +/** @internal */ export class StaticArray extends _StaticArray { private value?: NTuple private uint8ArrayValue?: Uint8Array @@ -413,6 +419,7 @@ export class StaticArray ext } } +/** @internal */ export class Address extends _Address { typeInfo: TypeInfo private value: StaticArray @@ -471,6 +478,7 @@ export class Address extends _Address { } } +/** @internal */ export class DynamicArray extends _DynamicArray { private value?: TItem[] private uint8ArrayValue?: Uint8Array @@ -576,6 +584,7 @@ export class DynamicArray extends _DynamicArray extends _Tuple { private value?: TTuple private uint8ArrayValue?: Uint8Array @@ -657,6 +666,7 @@ export class Tuple extends _Tu } } +/** @internal */ export class Struct extends (_Struct as DeliberateAny) { private uint8ArrayValue?: Uint8Array genericArgs: Record @@ -738,6 +748,7 @@ export class Struct extends (_Struct @@ -799,6 +810,7 @@ export class DynamicBytes extends _DynamicBytes { } } +/** @internal */ export class StaticBytes extends _StaticBytes { private value: StaticArray typeInfo: TypeInfo @@ -860,6 +872,7 @@ export class StaticBytes extends _StaticBytes extends _ReferenceArray { private _values: TItem[] typeInfo: TypeInfo @@ -914,6 +927,7 @@ export class ReferenceArray extends _ReferenceArray { } } +/** @internal */ export class FixedArray extends _FixedArray { private _values: NTuple private size: number @@ -1107,11 +1121,13 @@ const isDynamicLengthType = (value: _ARC4Encoded) => { ) } +/** @internal */ export function encodeArc4(sourceTypeInfoString: string | undefined, source: T): bytes { const arc4Encoded = getArc4Encoded(source, sourceTypeInfoString) return arc4Encoded.bytes } +/** @internal */ export function decodeArc4( sourceTypeInfoString: string, targetTypeInfoString: string, @@ -1125,6 +1141,7 @@ export function decodeArc4( return getNativeValue(source, targetTypeInfo) as T } +/** @internal */ export function interpretAsArc4( typeInfoString: string, bytes: StubBytesCompat, @@ -1134,6 +1151,7 @@ export function interpretAsArc4( return getEncoder(typeInfo)(bytes, typeInfo, prefix) } +/** @internal */ export const getArc4Encoded = (value: DeliberateAny, sourceTypeInfoString?: string): _ARC4Encoded => { if (value instanceof _ARC4Encoded) { return value @@ -1230,6 +1248,7 @@ export const getArc4Encoded = (value: DeliberateAny, sourceTypeInfoString?: stri throw new CodeError(`Unsupported type for encoding: ${typeof value}`) } +/** @internal */ export const toBytes = (val: unknown, sourceTypeInfoString?: string): bytes => { const uint64Val = asMaybeUint64Cls(val, false) if (uint64Val !== undefined) { @@ -1255,6 +1274,7 @@ export const toBytes = (val: unknown, sourceTypeInfoString?: string): bytes => { throw new InternalError(`Invalid type for bytes: ${nameOfType(val)}`) } +/** @internal */ export const getEncoder = (typeInfo: TypeInfo): fromBytes => { const mutableTupleFromBytes = (value: StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, prefix: 'none' | 'log' = 'none') => { const tuple = Tuple.fromBytes(value, typeInfo, prefix) diff --git a/src/impl/encoded-types/helpers.ts b/src/impl/encoded-types/helpers.ts index bb0bad2..1c1cc22 100644 --- a/src/impl/encoded-types/helpers.ts +++ b/src/impl/encoded-types/helpers.ts @@ -14,22 +14,31 @@ import { asBytes, asUint8Array } from '../../util' import { BigUint, Uint64 } from '../primitives' import type { fromBytes } from './types' +/** @internal */ export const validBitSizes = [...Array(64).keys()].map((x) => (x + 1) * 8) +/** @internal */ export const maxBigIntValue = (bitSize: number) => 2n ** BigInt(bitSize) - 1n +/** @internal */ export const maxBytesLength = (bitSize: number) => Math.floor(bitSize / BITS_IN_BYTE) +/** @internal */ export const regExpNxM = (maxPrecision: number) => new RegExp(`^\\d*\\.?\\d{0,${maxPrecision}}$`) +/** @internal */ export const trimTrailingDecimalZeros = (v: string) => v.replace(/(\d+\.\d*?)0+$/, '$1').replace(/\.$/, '') +/** @internal */ export const trimGenericTypeName = (typeName: string): string => typeName.replace(/<.*>/, '') +/** @internal */ export const areAllARC4Encoded = (items: T[]): items is T[] => items.every((item) => item instanceof ARC4Encoded) +/** @internal */ export const checkItemTypeName = (type: TypeInfo, value: ARC4Encoded) => { const typeName = trimGenericTypeName(type.name) const validTypeNames = [typeName] assert(validTypeNames.includes(value.constructor.name), `item must be of type ${typeName}, not ${value.constructor.name}`) } +/** @internal */ export const findBoolTypes = (values: TypeInfo[], index: number, delta: number): number => { // Helper function to find consecutive booleans from current index in a tuple. let until = 0 @@ -50,6 +59,7 @@ export const findBoolTypes = (values: TypeInfo[], index: number, delta: number): return until } +/** @internal */ export const getNativeValue = (value: DeliberateAny, targetTypeInfo: TypeInfo | undefined): DeliberateAny => { if (value.typeInfo && value.typeInfo.name === targetTypeInfo?.name) { return value @@ -79,16 +89,19 @@ export const getNativeValue = (value: DeliberateAny, targetTypeInfo: TypeInfo | return native } +/** @internal */ export const readLength = (value: Uint8Array): readonly [number, Uint8Array] => { const length = Number(encodingUtil.uint8ArrayToBigInt(value.slice(0, ABI_LENGTH_SIZE))) const data = value.slice(ABI_LENGTH_SIZE) return [length, data] } +/** @internal */ export const encodeLength = (length: number): BytesCls => { return asBytesCls(encodingUtil.bigIntToUint8Array(BigInt(length), ABI_LENGTH_SIZE)) } +/** @internal */ export const findBool = (values: ARC4Encoded[], index: number, delta: number) => { let until = 0 const length = values.length @@ -108,6 +121,7 @@ export const findBool = (values: ARC4Encoded[], index: number, delta: number) => return until } +/** @internal */ export const compressMultipleBool = (values: Bool[]): number => { let result = 0 if (values.length > 8) { @@ -122,6 +136,7 @@ export const compressMultipleBool = (values: Bool[]): number => { return result } +/** @internal */ export const holdsDynamicLengthContent = (value: TypeInfo): boolean => { const itemTypeName = trimGenericTypeName(value.name) @@ -146,30 +161,37 @@ export const holdsDynamicLengthContent = (value: TypeInfo): boolean => { ) } +/** @internal */ export const booleanFromBytes: fromBytes = (val) => { return encodingUtil.uint8ArrayToBigInt(asUint8Array(val)) > 0n } +/** @internal */ export const bigUintFromBytes: fromBytes = (val) => { return BigUint(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) } +/** @internal */ export const bytesFromBytes: fromBytes = (val) => { return asBytes(val) } +/** @internal */ export const stringFromBytes: fromBytes = (val) => { return asBytes(val).toString() } +/** @internal */ export const uint64FromBytes: fromBytes = (val) => { return Uint64(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) } +/** @internal */ export const onCompletionFromBytes: fromBytes = (val) => { return Uint64(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as OnCompleteAction } +/** @internal */ export const transactionTypeFromBytes: fromBytes = (val) => { return Uint64(encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as TransactionType } diff --git a/src/impl/encoded-types/index.ts b/src/impl/encoded-types/index.ts index bd7968d..f25a93d 100644 --- a/src/impl/encoded-types/index.ts +++ b/src/impl/encoded-types/index.ts @@ -1,3 +1,4 @@ +/** @internal */ export { Address, Bool, @@ -20,5 +21,7 @@ export { UFixed, Uint, } from './encoded-types' +/** @internal */ export { TypeInfo } from './types' +/** @internal */ export { arc4EncodedLength, getArc4TypeName, getMaxLengthOfStaticContentType, minLengthForType } from './utils' diff --git a/src/impl/encoded-types/types.ts b/src/impl/encoded-types/types.ts index bee383b..ca96b0a 100644 --- a/src/impl/encoded-types/types.ts +++ b/src/impl/encoded-types/types.ts @@ -3,14 +3,21 @@ import type { ARC4Encoded, BitSize } from '@algorandfoundation/algorand-typescri import type { StubBytesCompat } from '../primitives' +/** @internal */ export type CompatForArc4Int = N extends 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 ? Uint64Compat : BigUintCompat +/** @internal */ export type uFixedGenericArgs = { n: TypeInfo; m: TypeInfo } +/** @internal */ export type StaticArrayGenericArgs = { elementType: TypeInfo; size: TypeInfo } +/** @internal */ export type DynamicArrayGenericArgs = { elementType: TypeInfo } +/** @internal */ export type StructConstraint = Record +/** @internal */ export type TypeInfo = { name: string genericArgs?: TypeInfo[] | Record } +/** @internal */ export type fromBytes = (val: Uint8Array | StubBytesCompat, typeInfo: TypeInfo, prefix?: 'none' | 'log') => T diff --git a/src/impl/encoded-types/utils.ts b/src/impl/encoded-types/utils.ts index a696dab..2bc79fc 100644 --- a/src/impl/encoded-types/utils.ts +++ b/src/impl/encoded-types/utils.ts @@ -5,6 +5,7 @@ import { CodeError } from '../../errors' import { findBoolTypes, trimGenericTypeName } from './helpers' import type { DynamicArrayGenericArgs, StaticArrayGenericArgs, TypeInfo, uFixedGenericArgs } from './types' +/** @internal */ export const getMaxLengthOfStaticContentType = (type: TypeInfo, asArc4Encoded: boolean = true): number => { const getMaxBytesLengthForStaticArray = (typeInfo: { genericArgs: StaticArrayGenericArgs }) => { const genericArgs = typeInfo.genericArgs @@ -83,6 +84,7 @@ export const getMaxLengthOfStaticContentType = (type: TypeInfo, asArc4Encoded: b } } +/** @internal */ export const getArc4TypeName = ( typeInfo: TypeInfo, resourceEncoding: ResourceEncodingOptions | undefined = undefined, @@ -144,11 +146,13 @@ export const getArc4TypeName = ( return undefined } +/** @internal */ export const arc4EncodedLength = (typeInfoString: string): uint64 => { const typeInfo = JSON.parse(typeInfoString) return getMaxLengthOfStaticContentType(typeInfo, true) } +/** @internal */ export const minLengthForType = (typeInfo: TypeInfo): number | undefined => { try { return getMaxLengthOfStaticContentType(typeInfo, false) diff --git a/src/impl/ensure-budget.ts b/src/impl/ensure-budget.ts index 9e37971..ba1d964 100644 --- a/src/impl/ensure-budget.ts +++ b/src/impl/ensure-budget.ts @@ -1,6 +1,7 @@ import type { uint64 } from '@algorandfoundation/algorand-typescript' import { OpUpFeeSource } from '@algorandfoundation/algorand-typescript' +/** @internal */ export function ensureBudget(_budget: uint64, _feeSource: OpUpFeeSource = OpUpFeeSource.GroupCredit) { // ensureBudget function is emulated to be a no-op } diff --git a/src/impl/global.ts b/src/impl/global.ts index fd1afe9..7ac1c92 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -35,6 +35,7 @@ export class GlobalData { payoutsPercent: uint64 payoutsMinBalance: uint64 + /** @internal */ constructor() { this.minTxnFee = Uint64(MIN_TXN_FEE) this.minBalance = Uint64(DEFAULT_ACCOUNT_MIN_BALANCE) @@ -57,6 +58,7 @@ const getGlobalData = (): GlobalData => { const getMissingValueErrorMessage = (name: keyof GlobalData) => `'Global' object has no value set for attribute named '${name}'. Use \`context.ledger.patchGlobalData({${name}: your_value})\` to set the value in your test setup."` +/** @internal */ export const Global: typeof op.Global = { /** * microalgos diff --git a/src/impl/gtxn.ts b/src/impl/gtxn.ts index 76cb757..871e038 100644 --- a/src/impl/gtxn.ts +++ b/src/impl/gtxn.ts @@ -3,218 +3,228 @@ import { lazyContext } from '../context-helpers/internal-context' import { asUint64, asUint64Cls } from '../util' import type { StubUint64Compat } from './primitives' +/** @internal */ export const GTxn: typeof op.GTxn = { sender(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getTransaction(t).sender + return lazyContext.activeGroup.getTransaction(asUint64(t)).sender }, fee(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getTransaction(t).fee + return lazyContext.activeGroup.getTransaction(asUint64(t)).fee }, firstValid(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getTransaction(t).firstValid + return lazyContext.activeGroup.getTransaction(asUint64(t)).firstValid }, firstValidTime(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getTransaction(t).firstValidTime + return lazyContext.activeGroup.getTransaction(asUint64(t)).firstValidTime }, lastValid(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getTransaction(t).lastValid + return lazyContext.activeGroup.getTransaction(asUint64(t)).lastValid }, note(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getTransaction(t).note + return lazyContext.activeGroup.getTransaction(asUint64(t)).note }, lease(t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getTransaction(t).lease + return lazyContext.activeGroup.getTransaction(asUint64(t)).lease }, receiver(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getPaymentTransaction(t).receiver + return lazyContext.activeGroup.getPaymentTransaction(asUint64(t)).receiver }, - amount(t: uint64): uint64 { - return lazyContext.activeGroup.getPaymentTransaction(t).amount + amount(t: StubUint64Compat): uint64 { + return lazyContext.activeGroup.getPaymentTransaction(asUint64(t)).amount }, closeRemainderTo(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getPaymentTransaction(t).closeRemainderTo + return lazyContext.activeGroup.getPaymentTransaction(asUint64(t)).closeRemainderTo }, votePk(t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteKey + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).voteKey }, selectionPk(t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).selectionKey + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).selectionKey }, voteFirst(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteFirst + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).voteFirst }, voteLast(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteLast + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).voteLast }, voteKeyDilution(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteKeyDilution + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).voteKeyDilution }, type(t: StubUint64Compat): bytes { - return asUint64Cls(lazyContext.activeGroup.getTransaction(t).type).toBytes().asAlgoTs() + return asUint64Cls(lazyContext.activeGroup.getTransaction(asUint64(t)).type) + .toBytes() + .asAlgoTs() }, - typeEnum(t: uint64): uint64 { - return asUint64(lazyContext.activeGroup.getTransaction(t).type) + typeEnum(t: StubUint64Compat): uint64 { + return asUint64(lazyContext.activeGroup.getTransaction(asUint64(t)).type) }, xferAsset(t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getAssetTransferTransaction(t).xferAsset + return lazyContext.activeGroup.getAssetTransferTransaction(asUint64(t)).xferAsset }, assetAmount(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getAssetTransferTransaction(t).assetAmount + return lazyContext.activeGroup.getAssetTransferTransaction(asUint64(t)).assetAmount }, assetSender(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetTransferTransaction(t).assetSender + return lazyContext.activeGroup.getAssetTransferTransaction(asUint64(t)).assetSender }, assetReceiver(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetTransferTransaction(t).assetReceiver + return lazyContext.activeGroup.getAssetTransferTransaction(asUint64(t)).assetReceiver }, assetCloseTo(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetTransferTransaction(t).assetCloseTo + return lazyContext.activeGroup.getAssetTransferTransaction(asUint64(t)).assetCloseTo }, groupIndex(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getTransaction(t).groupIndex + return lazyContext.activeGroup.getTransaction(asUint64(t)).groupIndex }, txId(t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getTransaction(t).txnId + return lazyContext.activeGroup.getTransaction(asUint64(t)).txnId }, applicationId(t: StubUint64Compat): Application { - return lazyContext.activeGroup.getApplicationCallTransaction(t).appId + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).appId }, onCompletion(t: StubUint64Compat): uint64 { - const onCompletion = lazyContext.activeGroup.getApplicationCallTransaction(t).onCompletion + const onCompletion = lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).onCompletion return asUint64(onCompletion) }, applicationArgs(a: StubUint64Compat, b: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(a).appArgs(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).appArgs(asUint64(b)) }, numAppArgs(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numAppArgs + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numAppArgs }, accounts(a: StubUint64Compat, b: StubUint64Compat): Account { - return lazyContext.activeGroup.getApplicationCallTransaction(a).accounts(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).accounts(asUint64(b)) }, numAccounts(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numAccounts + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numAccounts }, approvalProgram(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(t).approvalProgram + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).approvalProgram }, clearStateProgram(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(t).clearStateProgram + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).clearStateProgram }, rekeyTo(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getTransaction(t).rekeyTo + return lazyContext.activeGroup.getTransaction(asUint64(t)).rekeyTo }, configAsset(t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getAssetConfigTransaction(t).configAsset + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).configAsset }, configAssetTotal(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getAssetConfigTransaction(t).total + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).total }, configAssetDecimals(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getAssetConfigTransaction(t).decimals + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).decimals }, configAssetDefaultFrozen(t: StubUint64Compat): boolean { - return lazyContext.activeGroup.getAssetConfigTransaction(t).defaultFrozen + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).defaultFrozen }, configAssetUnitName(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getAssetConfigTransaction(t).unitName + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).unitName }, configAssetName(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getAssetConfigTransaction(t).assetName + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).assetName }, configAssetUrl(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getAssetConfigTransaction(t).url + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).url }, configAssetMetadataHash(t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getAssetConfigTransaction(t).metadataHash + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).metadataHash }, configAssetManager(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetConfigTransaction(t).manager + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).manager }, configAssetReserve(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetConfigTransaction(t).reserve + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).reserve }, configAssetFreeze(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetConfigTransaction(t).freeze + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).freeze }, configAssetClawback(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetConfigTransaction(t).clawback + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).clawback }, freezeAsset(t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getAssetFreezeTransaction(t).freezeAsset + return lazyContext.activeGroup.getAssetFreezeTransaction(asUint64(t)).freezeAsset }, freezeAssetAccount(t: StubUint64Compat): Account { - return lazyContext.activeGroup.getAssetFreezeTransaction(t).freezeAccount + return lazyContext.activeGroup.getAssetFreezeTransaction(asUint64(t)).freezeAccount }, freezeAssetFrozen(t: StubUint64Compat): boolean { - return lazyContext.activeGroup.getAssetFreezeTransaction(t).frozen + return lazyContext.activeGroup.getAssetFreezeTransaction(asUint64(t)).frozen }, assets(a: StubUint64Compat, b: StubUint64Compat): Asset { - return lazyContext.activeGroup.getApplicationCallTransaction(a).assets(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).assets(asUint64(b)) }, numAssets(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numAssets + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numAssets }, applications(a: StubUint64Compat, b: StubUint64Compat): Application { - return lazyContext.activeGroup.getApplicationCallTransaction(a).apps(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).apps(asUint64(b)) }, numApplications(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numApps + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numApps }, globalNumUint(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).globalNumUint + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).globalNumUint }, globalNumByteSlice(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).globalNumBytes + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).globalNumBytes }, localNumUint(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).localNumUint + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).localNumUint }, localNumByteSlice(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).localNumBytes + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).localNumBytes }, extraProgramPages(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).extraProgramPages + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).extraProgramPages }, nonparticipation(t: StubUint64Compat): boolean { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).nonparticipation + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).nonparticipation }, logs(a: StubUint64Compat, b: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(a).logs(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).logs(asUint64(b)) }, numLogs(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numLogs + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numLogs }, createdAssetId(t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getAssetConfigTransaction(t).createdAsset + return lazyContext.activeGroup.getAssetConfigTransaction(asUint64(t)).createdAsset }, createdApplicationId(t: StubUint64Compat): Application { - return lazyContext.activeGroup.getApplicationCallTransaction(t).createdApp + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).createdApp }, lastLog(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(t).lastLog + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).lastLog }, stateProofPk(t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getKeyRegistrationTransaction(t).stateProofKey + return lazyContext.activeGroup.getKeyRegistrationTransaction(asUint64(t)).stateProofKey }, approvalProgramPages(a: StubUint64Compat, b: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(a).approvalProgramPages(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).approvalProgramPages(asUint64(b)) }, numApprovalProgramPages(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numApprovalProgramPages + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numApprovalProgramPages }, clearStateProgramPages(a: StubUint64Compat, b: StubUint64Compat): bytes { - return lazyContext.activeGroup.getApplicationCallTransaction(a).clearStateProgramPages(asUint64(b)) + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(a)).clearStateProgramPages(asUint64(b)) }, numClearStateProgramPages(t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getApplicationCallTransaction(t).numClearStateProgramPages + return lazyContext.activeGroup.getApplicationCallTransaction(asUint64(t)).numClearStateProgramPages }, } +/** @internal */ export const Transaction = (index: uint64) => lazyContext.txn.activeGroup.getTransaction(index) +/** @internal */ export const PaymentTxn = (index: uint64) => lazyContext.txn.activeGroup.getPaymentTransaction(index) +/** @internal */ export const KeyRegistrationTxn = (index: uint64) => lazyContext.txn.activeGroup.getKeyRegistrationTransaction(index) +/** @internal */ export const AssetConfigTxn = (index: uint64) => lazyContext.txn.activeGroup.getAssetConfigTransaction(index) +/** @internal */ export const AssetTransferTxn = (index: uint64) => lazyContext.txn.activeGroup.getAssetTransferTransaction(index) +/** @internal */ export const AssetFreezeTxn = (index: uint64) => lazyContext.txn.activeGroup.getAssetFreezeTransaction(index) +/** @internal */ export const ApplicationCallTxn = (index: uint64) => lazyContext.txn.activeGroup.getApplicationCallTransaction(index) diff --git a/src/impl/index.ts b/src/impl/index.ts index a90600c..ab0109b 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -1,18 +1,36 @@ +/** @internal */ export { AcctParams, appOptedIn, balance, minBalance } from './acct-params' +/** @internal */ export { AppGlobal } from './app-global' +/** @internal */ export { AppLocal } from './app-local' +/** @internal */ export { AppParams } from './app-params' +/** @internal */ export { AssetHolding } from './asset-holding' +/** @internal */ export { AssetParams } from './asset-params' +/** @internal */ export { Block } from './block' +/** @internal */ export { Box } from './box' +/** @internal */ export * from './crypto' +/** @internal */ export { Global } from './global' +/** @internal */ export { GTxn } from './gtxn' +/** @internal */ export { GITxn, ITxn, ITxnCreate } from './itxn' +/** @internal */ export { arg } from './logicSigArg' +/** @internal */ export { onlineStake } from './online-stake' +/** @internal */ export * from './pure' +/** @internal */ export { gloadBytes, gloadUint64, Scratch } from './scratch' +/** @internal */ export { gaid, Txn } from './txn' +/** @internal */ export { VoterParams } from './voter-params' diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 6a0f705..e88b71d 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -3,6 +3,7 @@ import type { Application as ApplicationType, Asset as AssetType, bytes, + BytesCompat, itxn, } from '@algorandfoundation/algorand-typescript' import { TransactionType } from '@algorandfoundation/algorand-typescript' @@ -21,7 +22,6 @@ import { getApp } from './app-params' import { getAsset } from './asset-params' import { encodeArc4 } from './encoded-types' import type { InnerTxn, InnerTxnFields } from './itxn' -import type { StubBytesCompat } from './primitives' import { Uint64Cls } from './primitives' import { Account, asAccount, asApplication, asAsset } from './reference' import type { Transaction } from './transactions' @@ -46,15 +46,16 @@ const mapCommonFields = ( ...rest, } } + export class PaymentInnerTxn extends PaymentTransaction implements itxn.PaymentInnerTxn { readonly isItxn?: true - /* @internal */ + /** @internal */ static create(fields: itxn.PaymentFields) { return new PaymentInnerTxn(fields) } - /* @internal */ + /** @internal */ constructor(fields: itxn.PaymentFields) { super({ ...mapCommonFields(fields), @@ -67,12 +68,12 @@ export class PaymentInnerTxn extends PaymentTransaction implements itxn.PaymentI export class KeyRegistrationInnerTxn extends KeyRegistrationTransaction implements itxn.KeyRegistrationInnerTxn { readonly isItxn?: true - /* @internal */ + /** @internal */ static create(fields: itxn.KeyRegistrationFields) { return new KeyRegistrationInnerTxn(fields) } - /* @internal */ + /** @internal */ constructor(fields: itxn.KeyRegistrationFields) { super(mapCommonFields(fields)) } @@ -81,12 +82,12 @@ export class KeyRegistrationInnerTxn extends KeyRegistrationTransaction implemen export class AssetConfigInnerTxn extends AssetConfigTransaction implements itxn.AssetConfigInnerTxn { readonly isItxn?: true - /* @internal */ + /** @internal */ static create(fields: itxn.AssetConfigFields) { return new AssetConfigInnerTxn(fields) } - /* @internal */ + /** @internal */ constructor(fields: itxn.AssetConfigFields) { const { assetName, unitName, url, manager, reserve, freeze, clawback, configAsset, ...rest } = mapCommonFields(fields) const createdAsset = @@ -121,7 +122,7 @@ export class AssetConfigInnerTxn extends AssetConfigTransaction implements itxn. export class AssetTransferInnerTxn extends AssetTransferTransaction implements itxn.AssetTransferInnerTxn { readonly isItxn?: true - /* @internal */ + /** @internal */ static create(fields: Partial) { if (fields.xferAsset === undefined) { throw new Error('xferAsset is required') @@ -129,7 +130,7 @@ export class AssetTransferInnerTxn extends AssetTransferTransaction implements i return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) } - /* @internal */ + /** @internal */ constructor(fields: itxn.AssetTransferFields) { super({ ...mapCommonFields(fields), @@ -144,7 +145,7 @@ export class AssetTransferInnerTxn extends AssetTransferTransaction implements i export class AssetFreezeInnerTxn extends AssetFreezeTransaction implements itxn.AssetFreezeInnerTxn { readonly isItxn?: true - /* @internal */ + /** @internal */ static create(fields: Partial) { if (fields.freezeAsset === undefined) { throw new Error('freezeAsset is required') @@ -152,7 +153,7 @@ export class AssetFreezeInnerTxn extends AssetFreezeTransaction implements itxn. return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) } - /* @internal */ + /** @internal */ constructor(fields: itxn.AssetFreezeFields) { const { freezeAsset, freezeAccount, ...rest } = mapCommonFields(fields) const asset: AssetType | undefined = freezeAsset instanceof Uint64Cls ? getAsset(freezeAsset) : (freezeAsset as AssetType) @@ -166,6 +167,7 @@ export class AssetFreezeInnerTxn extends AssetFreezeTransaction implements itxn. } } +/** @internal */ export type ApplicationCallFields = itxn.ApplicationCallFields & { createdApp?: ApplicationType appLogs?: Array @@ -174,12 +176,12 @@ export type ApplicationCallFields = itxn.ApplicationCallFields & { export class ApplicationCallInnerTxn extends ApplicationCallTransaction implements itxn.ApplicationCallInnerTxn { readonly isItxn?: true - /* @internal */ + /** @internal */ static create(fields: Partial) { return new ApplicationCallInnerTxn(fields) } - /* @internal */ + /** @internal */ constructor(fields: Partial) { const { appId, approvalProgram, clearStateProgram, onCompletion, appArgs, accounts, assets, apps, ...rest } = mapCommonFields(fields) super({ @@ -200,6 +202,7 @@ export class ApplicationCallInnerTxn extends ApplicationCallTransaction implemen } } +/** @internal */ export const createInnerTxn = (fields: TFields) => { switch (fields.type) { case TransactionType.Payment: @@ -219,28 +222,36 @@ export const createInnerTxn = (fields: TFields) } } +/** @internal */ export function submitGroup(...transactionFields: TFields): itxn.TxnFor { return transactionFields.map((f: (typeof transactionFields)[number]) => f.submit()) as itxn.TxnFor } +/** @internal */ export function payment(fields: itxn.PaymentFields): itxn.PaymentItxnParams { return new ItxnParams(fields, TransactionType.Payment) } +/** @internal */ export function keyRegistration(fields: itxn.KeyRegistrationFields): itxn.KeyRegistrationItxnParams { return new ItxnParams(fields, TransactionType.KeyRegistration) } +/** @internal */ export function assetConfig(fields: itxn.AssetConfigFields): itxn.AssetConfigItxnParams { return new ItxnParams(fields, TransactionType.AssetConfig) } +/** @internal */ export function assetTransfer(fields: itxn.AssetTransferFields): itxn.AssetTransferItxnParams { return new ItxnParams(fields, TransactionType.AssetTransfer) } +/** @internal */ export function assetFreeze(fields: itxn.AssetFreezeFields): itxn.AssetFreezeItxnParams { return new ItxnParams(fields, TransactionType.AssetFreeze) } +/** @internal */ export function applicationCall(fields: itxn.ApplicationCallFields): itxn.ApplicationCallItxnParams { return new ItxnParams(fields, TransactionType.ApplicationCall) } +/** @internal */ export class ItxnParams { #fields: TFields & { type: TransactionType } constructor(fields: TFields, type: TransactionType) { @@ -282,17 +293,19 @@ export class ItxnParams(this.#fields, this.#fields.type) } } + +/** @internal */ const UNSET = Symbol('UNSET_SYMBOL') /** * The ApplicationCallInnerTxnContext class is a specialized version of the ApplicationCallInnerTxn class. * It is used to handle the context of an application call transaction, including managing the return value. */ export class ApplicationCallInnerTxnContext extends ApplicationCallInnerTxn { - /* @internal */ + /** @internal */ static createFromFields(fields: ApplicationCallFields) { return new ApplicationCallInnerTxnContext(fields) } - /* @internal */ + /** @internal */ static createFromTypedApplicationCallFields( methodArgs: TypedApplicationCallFields, methodSelector: bytes, @@ -310,7 +323,7 @@ export class ApplicationCallInnerTxnContext extends Applicati } return new ApplicationCallInnerTxnContext(fields, transactions) } - /* @internal */ + /** @internal */ static createFromBareCreateApplicationCallFields(methodArgs: BareCreateApplicationCallFields) { return new ApplicationCallInnerTxnContext(methodArgs) } @@ -327,12 +340,12 @@ export class ApplicationCallInnerTxnContext extends Applicati this.appendLog(ABI_RETURN_VALUE_LOG_PREFIX.concat(encodeArc4(undefined, value))) this.#returnValue = value } - /* @internal */ + /** @internal */ get loggedReturnValue(): TReturn { return this.#returnValue === UNSET ? (undefined as TReturn) : this.#returnValue } - override appendLog(value: StubBytesCompat) { + override appendLog(value: BytesCompat) { /* As per https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0004.md#implementing-a-method If the method is non-void, the Application MUST encode the return value as described in the Encoding section and then log it with the @@ -342,6 +355,7 @@ export class ApplicationCallInnerTxnContext extends Applicati super.appendLog(value) } + /** @internal */ private constructor( fields: ApplicationCallFields, public itxns?: Transaction[], diff --git a/src/impl/itxn-compose.ts b/src/impl/itxn-compose.ts index 18f238a..3d43946 100644 --- a/src/impl/itxn-compose.ts +++ b/src/impl/itxn-compose.ts @@ -67,4 +67,5 @@ class ItxnCompose { } } +/** @internal */ export const itxnCompose: _ItxnCompose = new ItxnCompose() diff --git a/src/impl/itxn.ts b/src/impl/itxn.ts index a99de88..281e110 100644 --- a/src/impl/itxn.ts +++ b/src/impl/itxn.ts @@ -13,6 +13,7 @@ export type InnerTxn = | itxn.AssetFreezeInnerTxn | itxn.ApplicationCallInnerTxn +/** @internal */ export type InnerTxnFields = ( | itxn.PaymentFields | itxn.KeyRegistrationFields @@ -22,213 +23,243 @@ export type InnerTxnFields = ( | itxn.ApplicationCallFields ) & { type?: TransactionType } +const getInnerTxn = (index: StubUint64Compat): InnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(asUint64(index)) +} + +const getPaymentInnerTxn = (index: StubUint64Compat): itxn.PaymentInnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(asUint64(index)) +} + +const getKeyRegistrationInnerTxn = (index: StubUint64Compat): itxn.KeyRegistrationInnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(asUint64(index)) +} + +const getAssetTransferInnerTxn = (index: StubUint64Compat): itxn.AssetTransferInnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(asUint64(index)) +} + +const getAssetConfigInnerTxn = (index: StubUint64Compat): itxn.AssetConfigInnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(asUint64(index)) +} + +const getAssetFreezeInnerTxn = (index: StubUint64Compat): itxn.AssetFreezeInnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(asUint64(index)) +} + +const getApplicationCallInnerTxn = (index: StubUint64Compat): itxn.ApplicationCallInnerTxn => { + return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(asUint64(index)) +} + +/** @internal */ export const GITxn: typeof op.GITxn = { sender: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).sender + return getInnerTxn(t).sender }, fee: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).fee + return getInnerTxn(t).fee }, firstValid: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).firstValid + return getInnerTxn(t).firstValid }, firstValidTime: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).firstValidTime + return getInnerTxn(t).firstValidTime }, lastValid: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).lastValid + return getInnerTxn(t).lastValid }, note: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).note + return getInnerTxn(t).note }, lease: function (t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).lease + return getInnerTxn(t).lease }, receiver: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).receiver + return getPaymentInnerTxn(t).receiver }, amount: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).amount + return getPaymentInnerTxn(t).amount }, closeRemainderTo: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).closeRemainderTo + return getPaymentInnerTxn(t).closeRemainderTo }, votePk: function (t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteKey + return getKeyRegistrationInnerTxn(t).voteKey }, selectionPk: function (t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).selectionKey + return getKeyRegistrationInnerTxn(t).selectionKey }, voteFirst: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteFirst + return getKeyRegistrationInnerTxn(t).voteFirst }, voteLast: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteLast + return getKeyRegistrationInnerTxn(t).voteLast }, voteKeyDilution: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteKeyDilution + return getKeyRegistrationInnerTxn(t).voteKeyDilution }, type: function (t: StubUint64Compat): bytes { - return asUint64Cls(lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).type).toBytes().asAlgoTs() + return asUint64Cls(getInnerTxn(t).type).toBytes().asAlgoTs() }, typeEnum: function (t: StubUint64Compat): uint64 { - return asUint64(lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).type) + return asUint64(getInnerTxn(t).type) }, xferAsset: function (t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).xferAsset + return getAssetTransferInnerTxn(t).xferAsset }, assetAmount: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetAmount + return getAssetTransferInnerTxn(t).assetAmount }, assetSender: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetSender + return getAssetTransferInnerTxn(t).assetSender }, assetReceiver: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetReceiver + return getAssetTransferInnerTxn(t).assetReceiver }, assetCloseTo: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetCloseTo + return getAssetTransferInnerTxn(t).assetCloseTo }, groupIndex: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).groupIndex + return getInnerTxn(t).groupIndex }, txId: function (t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).txnId + return getInnerTxn(t).txnId }, applicationId: function (t: StubUint64Compat): Application { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).appId + return getApplicationCallInnerTxn(t).appId }, onCompletion: function (t: StubUint64Compat): uint64 { - const onCompletion = lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).onCompletion + const onCompletion = getApplicationCallInnerTxn(t).onCompletion return asUint64(onCompletion) }, applicationArgs: function (t: StubUint64Compat, a: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).appArgs(asUint64(a)) + return getApplicationCallInnerTxn(t).appArgs(asUint64(a)) }, numAppArgs: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numAppArgs + return getApplicationCallInnerTxn(t).numAppArgs }, accounts: function (t: StubUint64Compat, a: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).accounts(asUint64(a)) + return getApplicationCallInnerTxn(t).accounts(asUint64(a)) }, numAccounts: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numAccounts + return getApplicationCallInnerTxn(t).numAccounts }, approvalProgram: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).approvalProgram + return getApplicationCallInnerTxn(t).approvalProgram }, clearStateProgram: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).clearStateProgram + return getApplicationCallInnerTxn(t).clearStateProgram }, rekeyTo: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).rekeyTo + return getInnerTxn(t).rekeyTo }, configAsset: function (t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).configAsset + return getAssetConfigInnerTxn(t).configAsset }, configAssetTotal: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).total + return getAssetConfigInnerTxn(t).total }, configAssetDecimals: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).decimals + return getAssetConfigInnerTxn(t).decimals }, configAssetDefaultFrozen: function (t: StubUint64Compat): boolean { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).defaultFrozen + return getAssetConfigInnerTxn(t).defaultFrozen }, configAssetUnitName: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).unitName + return getAssetConfigInnerTxn(t).unitName }, configAssetName: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).assetName + return getAssetConfigInnerTxn(t).assetName }, configAssetUrl: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).url + return getAssetConfigInnerTxn(t).url }, configAssetMetadataHash: function (t: StubUint64Compat): bytes<32> { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).metadataHash + return getAssetConfigInnerTxn(t).metadataHash }, configAssetManager: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).manager + return getAssetConfigInnerTxn(t).manager }, configAssetReserve: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).reserve + return getAssetConfigInnerTxn(t).reserve }, configAssetFreeze: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).freeze + return getAssetConfigInnerTxn(t).freeze }, configAssetClawback: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).clawback + return getAssetConfigInnerTxn(t).clawback }, freezeAsset: function (t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).freezeAsset + return getAssetFreezeInnerTxn(t).freezeAsset }, freezeAssetAccount: function (t: StubUint64Compat): Account { - return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).freezeAccount + return getAssetFreezeInnerTxn(t).freezeAccount }, freezeAssetFrozen: function (t: StubUint64Compat): boolean { - return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).frozen + return getAssetFreezeInnerTxn(t).frozen }, assets: function (t: StubUint64Compat, a: StubUint64Compat): Asset { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).assets(asUint64(a)) + return getApplicationCallInnerTxn(t).assets(asUint64(a)) }, numAssets: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numAssets + return getApplicationCallInnerTxn(t).numAssets }, applications: function (t: StubUint64Compat, a: StubUint64Compat): Application { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).apps(asUint64(a)) + return getApplicationCallInnerTxn(t).apps(asUint64(a)) }, numApplications: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numApps + return getApplicationCallInnerTxn(t).numApps }, globalNumUint: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).globalNumUint + return getApplicationCallInnerTxn(t).globalNumUint }, globalNumByteSlice: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).globalNumBytes + return getApplicationCallInnerTxn(t).globalNumBytes }, localNumUint: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).localNumUint + return getApplicationCallInnerTxn(t).localNumUint }, localNumByteSlice: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).localNumBytes + return getApplicationCallInnerTxn(t).localNumBytes }, extraProgramPages: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).extraProgramPages + return getApplicationCallInnerTxn(t).extraProgramPages }, nonparticipation: function (t: StubUint64Compat): boolean { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).nonparticipation + return getKeyRegistrationInnerTxn(t).nonparticipation }, logs: function (t: StubUint64Compat, a: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).logs(asUint64(a)) + return getApplicationCallInnerTxn(t).logs(asUint64(a)) }, numLogs: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numLogs + return getApplicationCallInnerTxn(t).numLogs }, createdAssetId: function (t: StubUint64Compat): Asset { - return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).createdAsset + return getAssetConfigInnerTxn(t).createdAsset }, createdApplicationId: function (t: StubUint64Compat): Application { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).createdApp + return getApplicationCallInnerTxn(t).createdApp }, lastLog: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).lastLog + return getApplicationCallInnerTxn(t).lastLog }, stateProofPk: function (t: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).stateProofKey + return getKeyRegistrationInnerTxn(t).stateProofKey }, approvalProgramPages: function (t: StubUint64Compat, a: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).approvalProgramPages(asUint64(a)) + return getApplicationCallInnerTxn(t).approvalProgramPages(asUint64(a)) }, numApprovalProgramPages: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numApprovalProgramPages + return getApplicationCallInnerTxn(t).numApprovalProgramPages }, clearStateProgramPages: function (t: StubUint64Compat, a: StubUint64Compat): bytes { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).clearStateProgramPages(asUint64(a)) + return getApplicationCallInnerTxn(t).clearStateProgramPages(asUint64(a)) }, numClearStateProgramPages: function (t: StubUint64Compat): uint64 { - return lazyContext.activeGroup.getItxnGroup().getApplicationCallInnerTxn(t).numClearStateProgramPages + return getApplicationCallInnerTxn(t).numClearStateProgramPages }, } +/** @internal */ export const ITxn: typeof op.ITxn = { /** * 32 byte address @@ -649,6 +680,7 @@ const getConstructingItxn = (): T => { return lazyContext.activeGroup.constructingItxn as T } +/** @internal */ export const ITxnCreate: typeof op.ITxnCreate = { begin: function (): void { lazyContext.activeGroup.beginInnerTransactionGroup() diff --git a/src/impl/log.ts b/src/impl/log.ts index 01beb4c..8633130 100644 --- a/src/impl/log.ts +++ b/src/impl/log.ts @@ -4,6 +4,7 @@ import { lazyContext } from '../context-helpers/internal-context' import { toBytes } from './encoded-types' import type { StubBigUintCompat, StubBytesCompat, StubUint64Compat } from './primitives' +/** @internal */ export function log(...args: Array): void { lazyContext.txn.appendLog(args.map((a) => toBytes(a)).reduce((left, right) => left.concat(right))) } diff --git a/src/impl/logicSigArg.ts b/src/impl/logicSigArg.ts index e96ec9c..30c7b98 100644 --- a/src/impl/logicSigArg.ts +++ b/src/impl/logicSigArg.ts @@ -3,6 +3,7 @@ import { lazyContext } from '../context-helpers/internal-context' import { asNumber } from '../util' import type { StubUint64Compat } from './primitives' +/** @internal */ export const arg = (a: StubUint64Compat): bytes => { const index = asNumber(a) return lazyContext.value.activeLogicSigArgs[index] diff --git a/src/impl/match.ts b/src/impl/match.ts index dda748f..bdf7854 100644 --- a/src/impl/match.ts +++ b/src/impl/match.ts @@ -7,6 +7,7 @@ import { FixedArray } from './encoded-types/encoded-types' import type { StubBytesCompat, Uint64Cls } from './primitives' import { BytesCls } from './primitives' +/** @internal */ export const match: typeof _match = (subject, test): boolean => { if (Object.hasOwn(test, 'not')) { return !match(subject, (test as DeliberateAny).not) @@ -56,6 +57,7 @@ export const match: typeof _match = (subject, test): boolean => { return false } +/** @internal */ export const assertMatch: typeof _assertMatch = (subject, test, message): void => { const isMatching = match(subject, test) assert(isMatching, message) diff --git a/src/impl/method-selector.ts b/src/impl/method-selector.ts index 75f4a79..9d8e4a9 100644 --- a/src/impl/method-selector.ts +++ b/src/impl/method-selector.ts @@ -6,6 +6,7 @@ import type { Contract } from './contract' import { sha512_256 } from './crypto' import { Bytes } from './primitives' +/** @internal */ export const methodSelector = ( methodSignature: Parameters>[0], contract?: TContract | { new (): TContract }, diff --git a/src/impl/online-stake.ts b/src/impl/online-stake.ts index 4c47437..b3875f0 100644 --- a/src/impl/online-stake.ts +++ b/src/impl/online-stake.ts @@ -1,6 +1,7 @@ import type { op } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' +/** @internal */ export const onlineStake: typeof op.onlineStake = () => { return lazyContext.ledger.onlineStake } diff --git a/src/impl/primitives.ts b/src/impl/primitives.ts index a680d25..1a751f5 100644 --- a/src/impl/primitives.ts +++ b/src/impl/primitives.ts @@ -8,67 +8,35 @@ import { base32ToUint8Array } from './base-32' const MAX_UINT8 = 2 ** 8 - 1 const MAX_BYTES_SIZE = 4096 +/** @internal */ export type StubBigUintCompat = BigUintCompat | BigUintCls | Uint64Cls +/** @internal */ export type StubBytesCompat = BytesCompat | BytesCls +/** @internal */ export type StubUint64Compat = Uint64Compat | Uint64Cls -/** - * Converts internal Algorand type representations to their external primitive values. - * - * @overload - * @param {uint64} val - A uint64 value to convert - * @returns {bigint} The uint64 value as a bigint - * - * @overload - * @param {biguint} val - A biguint value to convert - * @returns {bigint} The biguint value as a bigint - * - * @overload - * @param {bytes} val - A bytes value to convert - * @returns {Uint8Array} The bytes value as a Uint8Array - * - * @overload - * @param {string} val - A string value to pass through - * @returns {string} The original string value unchanged - * - * @example - * ```ts - * const uint64Val = Uint64(123n) - * toExternalValue(uint64Val) // returns 123n - * - * const bytesVal = Bytes.fromBase64("SGVsbG8="); - * toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) - * ``` - */ -export function toExternalValue(val: uint64): bigint -export function toExternalValue(val: biguint): bigint -export function toExternalValue(val: bytes): Uint8Array -export function toExternalValue(val: string): string -export function toExternalValue(val: uint64 | biguint | bytes | string) { - const instance = val as unknown - if (instance instanceof BytesCls) return instance.asUint8Array() - if (instance instanceof Uint64Cls) return instance.asBigInt() - if (instance instanceof BigUintCls) return instance.asBigInt() - if (typeof val === 'string') return val -} - /** * Create a uint64 with the default value of 0 + * @internal */ export function Uint64(): uint64 /** + * @internal * Create a uint64 from a string literal */ export function Uint64(v: string): uint64 /** + * @internal * Create a uint64 from a bigint literal */ export function Uint64(v: bigint): uint64 /** + * @internal * Create a uint64 from a number literal */ export function Uint64(v: number): uint64 /** + * @internal * Create a uint64 from a boolean value. True is 1, False is 0 */ export function Uint64(v: boolean): uint64 @@ -80,30 +48,37 @@ export function Uint64(v?: Uint64Compat | string): uint64 { } /** + * @internal * Create a biguint from a bigint literal */ export function BigUint(v: bigint): biguint /** + * @internal * Create a biguint from a boolean value (true = 1, false = 0) */ export function BigUint(v: boolean): biguint /** + * @internal * Create a biguint from a uint64 value */ export function BigUint(v: uint64): biguint /** + * @internal * Create a biguint from a number literal */ export function BigUint(v: number): biguint /** + * @internal * Create a biguint from a byte array interpreted as a big-endian number */ export function BigUint(v: bytes): biguint /** + * @internal * Create a biguint from a string literal containing the decimal digits */ export function BigUint(v: string): biguint /** + * @internal * Create a biguint with the default value of 0 */ export function BigUint(): biguint @@ -114,9 +89,10 @@ export function BigUint(v?: BigUintCompat | string): biguint { } /** + * @internal * Create a byte array from a string interpolation template and compatible replacements - * @param value - * @param replacements + * @param value * + * @param replacements * */ export function FixedBytes( length: TLength, @@ -124,26 +100,32 @@ export function FixedBytes( ...replacements: BytesCompat[] ): bytes /** + * @internal * Create a byte array from a utf8 string */ export function FixedBytes(length: TLength, value: string): bytes /** + * @internal * No op, returns the provided byte array. */ export function FixedBytes(length: TLength, value: bytes): bytes /** - * Create a byte array from a biguint value encoded as a variable length big-endian number + * @internal + * Create a byte array from a biguint value encoded as a variable length big-endian number * */ export function FixedBytes(length: TLength, value: biguint): bytes /** + * @internal * Create a byte array from a uint64 value encoded as a fixed length 64-bit number */ export function FixedBytes(length: TLength, value: uint64): bytes /** + * @internal * Create a byte array from an Iterable where each item is interpreted as a single byte and must be between 0 and 255 inclusively */ export function FixedBytes(length: TLength, value: Iterable): bytes /** + * @internal * Create an empty byte array */ export function FixedBytes(length: TLength): bytes @@ -160,6 +142,7 @@ export function FixedBytes( } /** + * @internal * Create a new bytes value from a hexadecimal encoded string * @param hex */ @@ -171,6 +154,7 @@ FixedBytes.fromHex = (length: TLength, hex: str return result.toFixed({ length }) } /** + * @internal * Create a new bytes value from a base 64 encoded string * @param b64 */ @@ -183,6 +167,7 @@ FixedBytes.fromBase64 = (length: TLength, b64: } /** + * @internal * Create a new bytes value from a base 32 encoded string * @param b32 */ @@ -195,32 +180,39 @@ FixedBytes.fromBase32 = (length: TLength, b32: } /** + * @internal * Create a byte array from a string interpolation template and compatible replacements * @param value * @param replacements */ export function Bytes(value: TemplateStringsArray, ...replacements: BytesCompat[]): bytes /** + * @internal * Create a byte array from a utf8 string */ export function Bytes(value: string): bytes /** + * @internal * No op, returns the provided byte array. */ export function Bytes(value: bytes): bytes /** + * @internal * Create a byte array from a biguint value encoded as a variable length big-endian number */ export function Bytes(value: biguint): bytes /** + * @internal * Create a byte array from a uint64 value encoded as a fixed length 64-bit number */ export function Bytes(value: uint64): bytes /** + * @internal * Create a byte array from an Iterable where each item is interpreted as a single byte and must be between 0 and 255 inclusively */ export function Bytes(value: Iterable): bytes /** + * @internal * Create an empty byte array */ export function Bytes(): bytes @@ -247,6 +239,7 @@ export function Bytes( } /** + * @internal * Create a new bytes value from a hexadecimal encoded string * @param hex */ @@ -254,6 +247,7 @@ Bytes.fromHex = (hex: string): bytes => { return BytesCls.fromHex(hex).asAlgoTs() } /** + * @internal * Create a new bytes value from a base 64 encoded string * @param b64 */ @@ -262,6 +256,7 @@ Bytes.fromBase64 = (b64: string): bytes => { } /** + * @internal * Create a new bytes value from a base 32 encoded string * @param b32 */ @@ -270,6 +265,7 @@ Bytes.fromBase32 = (b32: string): bytes => { } /** + * @internal * Convert a StubUint64Compat value into a 'number' if possible. * This value may be negative * @param v @@ -288,33 +284,39 @@ export const getNumber = (v: StubUint64Compat): number => { throw new InternalError(`Cannot convert ${v} to number`) } +/** @internal */ export const getUint8Array = (v: StubBytesCompat): Uint8Array => { return BytesCls.fromCompat(v).asUint8Array() } +/** @internal */ export const isBytes = (v: unknown): v is StubBytesCompat => { if (typeof v === 'string') return true if (v instanceof BytesCls) return true return v instanceof Uint8Array } +/** @internal */ export const isUint64 = (v: unknown): v is StubUint64Compat => { if (typeof v == 'number') return true if (typeof v == 'bigint') return true return v instanceof Uint64Cls } +/** @internal */ export const checkUint64 = (v: bigint): bigint => { const u64 = BigInt.asUintN(64, v) if (u64 !== v) throw new AvmError(`Uint64 overflow or underflow`) return u64 } +/** @internal */ export const checkBigUint = (v: bigint): bigint => { const uBig = BigInt.asUintN(64 * 8, v) if (uBig !== v) throw new AvmError(`BigUint overflow or underflow`) return uBig } +/** @internal */ export const checkBytes = (v: Uint8Array): Uint8Array => { if (v.length > MAX_BYTES_SIZE) throw new AvmError(`Bytes length ${v.length} exceeds maximum length ${MAX_BYTES_SIZE}`) return v @@ -339,6 +341,7 @@ function isInstanceOfTypeByName(subject: unknown, typeCtor: { name: string }): b return false } +/** @internal */ export abstract class AlgoTsPrimitiveCls { static [Symbol.hasInstance](x: unknown): x is AlgoTsPrimitiveCls { return isInstanceOfTypeByName(x, AlgoTsPrimitiveCls) @@ -348,6 +351,7 @@ export abstract class AlgoTsPrimitiveCls { abstract toBytes(): BytesCls } +/** @internal */ export class Uint64Cls extends AlgoTsPrimitiveCls { readonly #value: bigint constructor(value: bigint | number | string) { @@ -397,6 +401,7 @@ export class Uint64Cls extends AlgoTsPrimitiveCls { return this.#value.toString() } } +/** @internal */ export class BigUintCls extends AlgoTsPrimitiveCls { readonly #value: bigint constructor(value: bigint) { @@ -447,6 +452,7 @@ function isTemplateStringsArray(v: unknown): v is TemplateStringsArray { return Boolean(v) && Array.isArray(v) && typeof v[0] === 'string' } +/** @internal */ export class BytesCls extends AlgoTsPrimitiveCls { readonly #v: Uint8Array constructor( @@ -598,6 +604,7 @@ export class BytesCls extends AlgoTsPrimitiveCls { } } +/** @internal */ export const arrayUtil = new (class ArrayUtil { arrayAt(arrayLike: Uint8Array, index: StubUint64Compat): Uint8Array arrayAt(arrayLike: readonly T[], index: StubUint64Compat): T diff --git a/src/impl/pure.ts b/src/impl/pure.ts index a27b2f0..0089a64 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -6,6 +6,7 @@ import { asBigUint, asBytes, asBytesCls, asMaybeBytesCls, asMaybeUint64Cls, asUi import type { StubBigUintCompat, StubBytesCompat, StubUint64Compat } from './primitives' import { BigUintCls, Bytes, BytesCls, checkBigUint, isUint64, Uint64, Uint64Cls } from './primitives' +/** @internal */ export const addw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64, uint64] => { const uint64A = Uint64Cls.fromCompat(a) const uint64B = Uint64Cls.fromCompat(b) @@ -13,6 +14,7 @@ export const addw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64 return toUint128(sum) } +/** @internal */ export const base64Decode = (e: Base64, a: StubBytesCompat): bytes => { const encoding = e === Base64.StdEncoding ? 'base64' : 'base64url' const bytesValue = BytesCls.fromCompat(a) @@ -27,6 +29,7 @@ export const base64Decode = (e: Base64, a: StubBytesCompat): bytes => { return Bytes(uint8ArrayResult) } +/** @internal */ export const bitLength = (a: StubUint64Compat | StubBytesCompat): uint64 => { const uint64Cls = asMaybeUint64Cls(a) const bigUintCls = asMaybeBytesCls(a)?.toBigUint() @@ -35,6 +38,7 @@ export const bitLength = (a: StubUint64Compat | StubBytesCompat): uint64 => { return Uint64(binaryValue.length) } +/** @internal */ export const bsqrt = (a: StubBigUintCompat): biguint => { const bigUintClsValue = BigUintCls.fromCompat(a) const bigintValue = checkBigUint(bigUintClsValue.asBigInt()) @@ -42,6 +46,7 @@ export const bsqrt = (a: StubBigUintCompat): biguint => { return asBigUint(sqrtValue) } +/** @internal */ export const btoi = (a: StubBytesCompat): uint64 => { const bytesValue = BytesCls.fromCompat(a) if (bytesValue.length.asAlgoTs() > BITS_IN_BYTE) { @@ -50,6 +55,7 @@ export const btoi = (a: StubBytesCompat): uint64 => { return bytesValue.toUint64().asAlgoTs() } +/** @internal */ export const bzero = (a: StubUint64Compat): bytes => { const size = Uint64Cls.fromCompat(a).asBigInt() if (size > MAX_BYTES_SIZE) { @@ -58,12 +64,14 @@ export const bzero = (a: StubUint64Compat): bytes => { return Bytes(new Uint8Array(Number(size))) } +/** @internal */ export const concat = (a: StubBytesCompat, b: StubBytesCompat): bytes => { const bytesA = BytesCls.fromCompat(a) const bytesB = BytesCls.fromCompat(b) return bytesA.concat(bytesB).asAlgoTs() } +/** @internal */ export const divmodw = ( a: StubUint64Compat, b: StubUint64Compat, @@ -78,12 +86,14 @@ export const divmodw = ( return [...toUint128(div), ...toUint128(mod)] } +/** @internal */ export const divw = (a: StubUint64Compat, b: StubUint64Compat, c: StubUint64Compat): uint64 => { const i = uint128ToBigInt(a, b) const j = Uint64Cls.fromCompat(c).asBigInt() return Uint64(i / j) } +/** @internal */ export const exp = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { const base = Uint64Cls.fromCompat(a).asBigInt() const exponent = Uint64Cls.fromCompat(b).asBigInt() @@ -93,6 +103,7 @@ export const exp = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { return Uint64(base ** exponent) } +/** @internal */ export const expw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64, uint64] => { const base = Uint64Cls.fromCompat(a).asBigInt() const exponent = Uint64Cls.fromCompat(b).asBigInt() @@ -104,6 +115,7 @@ export const expw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64 type ExtractType = ((a: StubBytesCompat, b: StubUint64Compat) => bytes) & ((a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat) => bytes) +/** @internal */ export const extract = ((a: StubBytesCompat, b: StubUint64Compat, c?: StubUint64Compat): bytes => { const bytesValue = BytesCls.fromCompat(a) const bytesLength = bytesValue.length.asBigInt() @@ -122,24 +134,28 @@ export const extract = ((a: StubBytesCompat, b: StubUint64Compat, c?: StubUint64 return bytesValue.slice(start, end).asAlgoTs() }) as ExtractType +/** @internal */ export const extractUint16 = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const result = extract(a, b, 2) const bytesResult = BytesCls.fromCompat(result) return bytesResult.toUint64().asAlgoTs() } +/** @internal */ export const extractUint32 = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const result = extract(a, b, 4) const bytesResult = BytesCls.fromCompat(result) return bytesResult.toUint64().asAlgoTs() } +/** @internal */ export const extractUint64 = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const result = extract(a, b, 8) const bytesResult = BytesCls.fromCompat(result) return bytesResult.toUint64().asAlgoTs() } +/** @internal */ export const getBit = (a: StubUint64Compat | StubBytesCompat, b: StubUint64Compat): uint64 => { const binaryString = toBinaryString(isUint64(a) ? asUint64Cls(a).toBytes().asAlgoTs() : asBytes(a)) const index = Uint64Cls.fromCompat(b).asNumber() @@ -150,6 +166,7 @@ export const getBit = (a: StubUint64Compat | StubBytesCompat, b: StubUint64Compa return binaryString[adjustedIndex] === '1' ? 1 : 0 } +/** @internal */ export const getByte = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { const bytesValue = BytesCls.fromCompat(a) const index = Uint64Cls.fromCompat(b).asNumber() @@ -159,14 +176,17 @@ export const getByte = (a: StubBytesCompat, b: StubUint64Compat): uint64 => { return bytesValue.at(index).toUint64().asAlgoTs() } +/** @internal */ export const itob = (a: StubUint64Compat): bytes => { return asUint64Cls(a).toBytes().asAlgoTs() } +/** @internal */ export const len = (a: StubBytesCompat): uint64 => { return asBytesCls(a).length.asAlgoTs() } +/** @internal */ export const mulw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64, uint64] => { const uint64A = Uint64Cls.fromCompat(a) const uint64B = Uint64Cls.fromCompat(b) @@ -174,6 +194,7 @@ export const mulw = (a: StubUint64Compat, b: StubUint64Compat): readonly [uint64 return toUint128(product) } +/** @internal */ export const replace = (a: StubBytesCompat, b: StubUint64Compat, c: StubBytesCompat): bytes => { const bytesValue = BytesCls.fromCompat(a) const index = Uint64Cls.fromCompat(b).asNumber() @@ -194,6 +215,7 @@ export const replace = (a: StubBytesCompat, b: StubUint64Compat, c: StubBytesCom type selectType = ((a: StubBytesCompat, b: StubBytesCompat, c: StubUint64Compat) => bytes) & ((a: StubUint64Compat, b: StubUint64Compat, c: StubUint64Compat) => uint64) +/** @internal */ export const select = (( a: StubUint64Compat | StubBytesCompat, b: StubUint64Compat | StubBytesCompat, @@ -211,6 +233,7 @@ export const select = (( type SetBitType = ((target: StubBytesCompat, n: StubUint64Compat, c: StubUint64Compat) => bytes) & ((target: StubUint64Compat, n: StubUint64Compat, c: StubUint64Compat) => uint64) +/** @internal */ export const setBit = ((a: StubUint64Compat | StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat) => { const uint64Cls = asMaybeUint64Cls(a) const indexParam = Uint64Cls.fromCompat(b).asNumber() @@ -229,6 +252,7 @@ export const setBit = ((a: StubUint64Compat | StubBytesCompat, b: StubUint64Comp } }) as SetBitType +/** @internal */ export const setByte = (a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat): bytes => { const binaryString = toBinaryString(BytesCls.fromCompat(a).asAlgoTs()) @@ -249,6 +273,7 @@ export const setByte = (a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Co return updatedBytes.asAlgoTs() } +/** @internal */ export const shl = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { const uint64A = Uint64Cls.fromCompat(a) const uint64B = Uint64Cls.fromCompat(b) @@ -261,6 +286,7 @@ export const shl = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { return Uint64(shifted) } +/** @internal */ export const shr = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { const uint64A = Uint64Cls.fromCompat(a) const uint64B = Uint64Cls.fromCompat(b) @@ -273,12 +299,14 @@ export const shr = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { return Uint64(shifted) } +/** @internal */ export const sqrt = (a: StubUint64Compat): uint64 => { const bigIntValue = Uint64Cls.fromCompat(a).asBigInt() const sqrtValue = squareroot(bigIntValue) return Uint64(sqrtValue) } +/** @internal */ export const substring = (a: StubBytesCompat, b: StubUint64Compat, c: StubUint64Compat): bytes => { const bytesValue = BytesCls.fromCompat(a) const start = Uint64Cls.fromCompat(b).asBigInt() @@ -292,6 +320,7 @@ export const substring = (a: StubBytesCompat, b: StubUint64Compat, c: StubUint64 return bytesValue.slice(start, end).asAlgoTs() } +/** @internal */ export const JsonRef = new Proxy({} as typeof op.JsonRef, { get: (_target, prop) => { throw new NotImplementedError(`JsonRef.${prop.toString()}`) diff --git a/src/impl/reference.ts b/src/impl/reference.ts index 2850acf..a15fe79 100644 --- a/src/impl/reference.ts +++ b/src/impl/reference.ts @@ -32,6 +32,8 @@ import type { GlobalStateCls, LocalStateCls } from './state' export class AssetHolding { balance: uint64 frozen: boolean + + /** @internal */ constructor(balance: StubUint64Compat, frozen: boolean) { this.balance = asUint64(balance) this.frozen = frozen @@ -46,6 +48,7 @@ export class AccountData { lastHeartbeat?: uint64 account: Mutable> + /** @internal */ constructor() { this.account = { totalAppsCreated: 0, @@ -64,10 +67,12 @@ export class AccountData { } } +/** @internal */ export function Account(address?: bytes): AccountType { return new AccountCls(address) } +/** @internal */ export class AccountCls extends BytesBackedCls implements AccountType { constructor(address?: bytes) { const addressBytes = address ?? ZERO_ADDRESS @@ -143,8 +148,10 @@ export class ApplicationData { materialisedBoxes: BytesMap } + /** @internal */ isCreating: boolean = false + /** @internal */ constructor() { this.application = { approvalProgram: ALWAYS_APPROVE_TEAL_PROGRAM, @@ -165,10 +172,12 @@ export class ApplicationData { } } +/** @internal */ export function Application(id?: uint64): ApplicationType { return new ApplicationCls(id) } +/** @internal */ export class ApplicationCls extends Uint64BackedCls implements ApplicationType { get id() { return this.uint64 @@ -215,6 +224,7 @@ export class ApplicationCls extends Uint64BackedCls implements ApplicationType { } export type AssetData = Mutable> +/** @internal */ export const getDefaultAssetData = (): AssetData => ({ total: lazyContext.any.uint64(), decimals: lazyContext.any.uint64(1, 6), @@ -230,10 +240,12 @@ export const getDefaultAssetData = (): AssetData => ({ reserve: Account(ZERO_ADDRESS), }) +/** @internal */ export function Asset(id?: uint64): AssetType { return new AssetCls(id) } +/** @internal */ export class AssetCls extends Uint64BackedCls implements AssetType { get id(): uint64 { return this.uint64 @@ -302,10 +314,12 @@ export class AssetCls extends Uint64BackedCls implements AssetType { } } +/** @internal */ export const checksumFromPublicKey = (pk: Uint8Array): Uint8Array => { return Uint8Array.from(js_sha512.sha512_256.array(pk).slice(HASH_BYTES_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH)) } +/** @internal */ export const getApplicationAddress = (appId: StubUint64Compat): AccountType => { const toBeSigned = conactUint8Arrays(asUint8Array(APP_ID_PREFIX), encodingUtil.bigIntToUint8Array(asBigInt(appId), 8)) const appIdHash = js_sha512.sha512_256.array(toBeSigned) @@ -314,16 +328,19 @@ export const getApplicationAddress = (appId: StubUint64Compat): AccountType => { return Account(Bytes.fromBase32(address)) } +/** @internal */ export const encodeAddress = (address: Uint8Array): string => { const checksum = checksumFromPublicKey(address) return encodingUtil.uint8ArrayToBase32(conactUint8Arrays(address, checksum)).slice(0, ALGORAND_ADDRESS_LENGTH) } +/** @internal */ export const decodePublicKey = (address: string): Uint8Array => { const decoded = encodingUtil.base32ToUint8Array(address) return decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH) } +/** @internal */ export const asAccount = (val: AccountType | bytes | string | undefined): AccountType | undefined => { return val instanceof AccountCls ? val @@ -334,10 +351,12 @@ export const asAccount = (val: AccountType | bytes | string | undefined): Accoun : undefined } +/** @internal */ export const asAsset = (val: AssetType | uint64 | undefined): AssetType | undefined => { return val instanceof Uint64Cls ? Asset(val.asAlgoTs()) : val instanceof AssetCls ? val : undefined } +/** @internal */ export const asApplication = (val: ApplicationType | uint64 | undefined): ApplicationType | undefined => { return val instanceof Uint64Cls ? Application(val.asAlgoTs()) : val instanceof ApplicationCls ? val : undefined } diff --git a/src/impl/scratch.ts b/src/impl/scratch.ts index 4f48d8d..b9659f8 100644 --- a/src/impl/scratch.ts +++ b/src/impl/scratch.ts @@ -1,43 +1,47 @@ -import type { bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import type { bytes, BytesCompat, op, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { InternalError } from '../errors' +import { asUint64 } from '../util' import type { StubBytesCompat, StubUint64Compat } from './primitives' import { BytesCls, Uint64Cls } from './primitives' +/** @internal */ export const gloadUint64: typeof op.gloadUint64 = (a: StubUint64Compat, b: StubUint64Compat): uint64 => { - const txn = lazyContext.activeGroup.getTransaction(a) - const result = txn.getScratchSlot(b) + const txn = lazyContext.activeGroup.getTransaction(asUint64(a)) + const result = txn.getScratchSlot(asUint64(b)) if (result instanceof Uint64Cls) { return result.asAlgoTs() } throw new InternalError('invalid scratch slot type') } +/** @internal */ export const gloadBytes: typeof op.gloadBytes = (a: StubUint64Compat, b: StubUint64Compat): bytes => { - const txn = lazyContext.activeGroup.getTransaction(a) - const result = txn.getScratchSlot(b) + const txn = lazyContext.activeGroup.getTransaction(asUint64(a)) + const result = txn.getScratchSlot(asUint64(b)) if (result instanceof BytesCls) { return result.asAlgoTs() } throw new InternalError('invalid scratch slot type') } +/** @internal */ export const Scratch: typeof op.Scratch = { loadBytes: function (a: StubUint64Compat): bytes { - const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) + const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(asUint64(a)) if (result instanceof BytesCls) { return result as bytes } throw new InternalError('invalid scratch slot type') }, loadUint64: function (a: StubUint64Compat): uint64 { - const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) + const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(asUint64(a)) if (result instanceof Uint64Cls) { return result as uint64 } throw new InternalError('invalid scratch slot type') }, store: function (a: StubUint64Compat, b: StubUint64Compat | StubBytesCompat): void { - lazyContext.activeGroup.activeTransaction.setScratchSlot(a, b) + lazyContext.activeGroup.activeTransaction.setScratchSlot(asUint64(a), b as unknown as Uint64Compat | BytesCompat) }, } diff --git a/src/impl/state.ts b/src/impl/state.ts index 9fdb4c3..c7cd694 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -24,9 +24,12 @@ import type { StubBytesCompat, StubUint64Compat } from './primitives' import { Bytes, Uint64, Uint64Cls } from './primitives' export class GlobalStateCls { + /** @internal */ private readonly _type: string = GlobalStateCls.name + /** @internal */ #value: ValueType | undefined + key: bytes | undefined get hasKey(): boolean { @@ -60,6 +63,7 @@ export class GlobalStateCls { return this.#value !== undefined } + /** @internal */ constructor(key?: bytes | string, value?: ValueType) { this.key = key !== undefined ? asBytes(key) : undefined this.#value = value @@ -67,7 +71,9 @@ export class GlobalStateCls { } export class LocalStateCls { + /** @internal */ #value: ValueType | undefined + delete: () => void = () => { if (this.#value instanceof Uint64Cls) { this.#value = Uint64(0) as ValueType @@ -92,8 +98,10 @@ export class LocalStateCls { } export class LocalStateMapCls { + /** @internal */ private applicationId: uint64 + /** @internal */ constructor() { this.applicationId = lazyContext.activeGroup.activeApplicationId } @@ -107,6 +115,7 @@ export class LocalStateMapCls { return localStateMap.getOrFail(account) as LocalStateCls } + /** @internal */ private ensureApplicationLocalStateMap(key: bytes | string) { const applicationData = lazyContext.ledger.applicationDataMap.getOrFail(this.applicationId)!.application if (!applicationData.localStateMaps.has(key)) { @@ -116,10 +125,12 @@ export class LocalStateMapCls { } } +/** @internal */ export function GlobalState(options?: GlobalStateOptions): GlobalStateType { return new GlobalStateCls(options?.key, options?.initialValue) } +/** @internal */ export function LocalState(options?: { key?: bytes | string }): LocalStateType { function localStateInternal(account: Account): LocalStateForAccount { return localStateInternal.map.getValue(localStateInternal.key, account) @@ -130,6 +141,7 @@ export function LocalState(options?: { key?: bytes | string }): Local return localStateInternal } +/** @internal */ export class BoxCls { #key: bytes | undefined #app: Application @@ -191,7 +203,7 @@ export class BoxCls { } const original = lazyContext.ledger.getBox(this.#app, this.key) materialised = this.fromBytes(original) - lazyContext.ledger.setMatrialisedBox(this.#app, this.key, materialised) + lazyContext.ledger.setMaterialisedBox(this.#app, this.key, materialised) return materialised } set value(v: TValue) { @@ -204,7 +216,7 @@ export class BoxCls { } } lazyContext.ledger.setBox(this.#app, this.key, newValueBytes) - lazyContext.ledger.setMatrialisedBox(this.#app, this.key, v) + lazyContext.ledger.setMaterialisedBox(this.#app, this.key, v) } get hasKey(): boolean { @@ -252,6 +264,7 @@ export class BoxCls { } } +/** @internal */ export class BoxMapCls { private _keyPrefix: bytes | undefined #app: Application @@ -293,6 +306,7 @@ export class BoxMapCls { } } +/** @internal */ export class BoxRefCls { #key: bytes | undefined #app: Application @@ -462,10 +476,12 @@ export class BoxRefCls { } } +/** @internal */ export function Box(options?: { key: bytes | string }): BoxType { return new BoxCls(options?.key) } +/** @internal */ export function BoxMap(options?: { keyPrefix: bytes | string }): BoxMapType { const boxMap = new BoxMapCls() if (options?.keyPrefix !== undefined) { @@ -476,6 +492,7 @@ export function BoxMap(options?: { keyPrefix: bytes | string }): B return Object.setPrototypeOf(x, boxMap) } +/** @internal */ export function BoxRef(options?: { key: bytes | string }): BoxRefType { return new BoxRefCls(options?.key) } diff --git a/src/impl/template-var.ts b/src/impl/template-var.ts index ee9df5b..4904fd5 100644 --- a/src/impl/template-var.ts +++ b/src/impl/template-var.ts @@ -2,6 +2,7 @@ import { DEFAULT_TEMPLATE_VAR_PREFIX } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { CodeError } from '../errors' +/** @internal */ export function TemplateVar(variableName: string, prefix = DEFAULT_TEMPLATE_VAR_PREFIX): T { const key = prefix + variableName if (!Object.hasOwn(lazyContext.value.templateVars, key)) { diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index 1c7aacf..84c59d5 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -3,8 +3,10 @@ import type { Application as ApplicationType, Asset as AssetType, bytes, + BytesCompat, gtxn, uint64, + Uint64Compat, } from '@algorandfoundation/algorand-typescript' import { OnCompleteAction, TransactionType } from '@algorandfoundation/algorand-typescript' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_ITEMS_IN_LOG } from '../constants' @@ -13,9 +15,10 @@ import { InternalError } from '../errors' import type { Mutable, ObjectKeys } from '../typescript-helpers' import { asBytes, asMaybeBytesCls, asMaybeUint64Cls, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' import { toBytes } from './encoded-types' -import { Bytes, Uint64, type StubBytesCompat, type StubUint64Compat } from './primitives' +import { Bytes, Uint64, type StubBytesCompat } from './primitives' import { Account, Application, Asset } from './reference' +/** @internal */ const baseDefaultFields = () => ({ sender: lazyContext.defaultSender, fee: Uint64(0), @@ -32,6 +35,7 @@ const baseDefaultFields = () => ({ export type TxnFields = Partial>>> abstract class TransactionBase { + /** @internal */ protected constructor(fields: Partial>) { const baseDefaults = baseDefaultFields() this.sender = fields.sender ?? baseDefaults.sender @@ -59,7 +63,7 @@ abstract class TransactionBase { readonly rekeyTo: AccountType readonly scratchSpace: Array - setScratchSlot(index: StubUint64Compat, value: StubBytesCompat | StubUint64Compat): void { + setScratchSlot(index: Uint64Compat, value: BytesCompat | Uint64Compat): void { const i = asNumber(index) if (i >= this.scratchSpace.length) { throw new InternalError('invalid scratch slot') @@ -69,7 +73,7 @@ abstract class TransactionBase { this.scratchSpace[i] = bytesValue?.asAlgoTs() ?? uint64Value?.asAlgoTs() ?? Uint64(0) } - getScratchSlot(index: StubUint64Compat): bytes | uint64 { + getScratchSlot(index: Uint64Compat): bytes | uint64 { const i = asNumber(index) if (i >= this.scratchSpace.length) { throw new InternalError('invalid scratch slot') @@ -79,11 +83,12 @@ abstract class TransactionBase { } export class PaymentTransaction extends TransactionBase implements gtxn.PaymentTxn { - /* @internal */ + /** @internal */ static create(fields: TxnFields) { return new PaymentTransaction(fields) } + /** @internal */ protected constructor(fields: TxnFields) { super(fields) this.receiver = fields.receiver ?? Account() @@ -99,11 +104,12 @@ export class PaymentTransaction extends TransactionBase implements gtxn.PaymentT } export class KeyRegistrationTransaction extends TransactionBase implements gtxn.KeyRegistrationTxn { - /* @internal */ + /** @internal */ static create(fields: TxnFields) { return new KeyRegistrationTransaction(fields) } + /** @internal */ protected constructor(fields: TxnFields) { super(fields) this.voteKey = fields.voteKey ?? (Bytes() as bytes<32>) @@ -133,11 +139,12 @@ export class KeyRegistrationTransaction extends TransactionBase implements gtxn. } export class AssetConfigTransaction extends TransactionBase implements gtxn.AssetConfigTxn { - /* @internal */ + /** @internal */ static create(fields: TxnFields) { return new AssetConfigTransaction(fields) } + /** @internal */ protected constructor(fields: TxnFields) { super(fields) this.configAsset = fields.configAsset ?? Asset() @@ -173,11 +180,12 @@ export class AssetConfigTransaction extends TransactionBase implements gtxn.Asse } export class AssetTransferTransaction extends TransactionBase implements gtxn.AssetTransferTxn { - /* @internal */ + /** @internal */ static create(fields: TxnFields) { return new AssetTransferTransaction(fields) } + /** @internal */ protected constructor(fields: TxnFields) { super(fields) this.xferAsset = fields.xferAsset ?? Asset() @@ -198,11 +206,12 @@ export class AssetTransferTransaction extends TransactionBase implements gtxn.As } export class AssetFreezeTransaction extends TransactionBase implements gtxn.AssetFreezeTxn { - /* @internal */ + /** @internal */ static create(fields: TxnFields) { return new AssetFreezeTransaction(fields) } + /** @internal */ protected constructor(fields: TxnFields) { super(fields) this.freezeAsset = fields.freezeAsset ?? Asset() @@ -231,10 +240,11 @@ export type ApplicationCallTransactionFields = TxnFields export class ApplicationCallTransaction extends TransactionBase implements gtxn.ApplicationCallTxn { - /* @internal */ + /** @internal */ static create(fields: ApplicationCallTransactionFields) { return new ApplicationCallTransaction(fields) } + /** @internal */ private args: Array #accounts: Array #assets: Array @@ -244,6 +254,7 @@ export class ApplicationCallTransaction extends TransactionBase implements gtxn. #appLogs: Array #appId: ApplicationType + /** @internal */ protected constructor(fields: ApplicationCallTransactionFields) { super(fields) this.#appId = fields.appId ?? Application() @@ -324,43 +335,43 @@ export class ApplicationCallTransaction extends TransactionBase implements gtxn. get apfa() { return this.#apps } - appArgs(index: StubUint64Compat): bytes { + appArgs(index: Uint64Compat): bytes { return toBytes(this.args[asNumber(index)]) } - accounts(index: StubUint64Compat): AccountType { + accounts(index: Uint64Compat): AccountType { return this.#accounts[asNumber(index)] } - assets(index: StubUint64Compat): AssetType { + assets(index: Uint64Compat): AssetType { return this.#assets[asNumber(index)] } - apps(index: StubUint64Compat): ApplicationType { + apps(index: Uint64Compat): ApplicationType { return this.#apps[asNumber(index)] } - approvalProgramPages(index: StubUint64Compat): bytes { + approvalProgramPages(index: Uint64Compat): bytes { return combineIntoMaxBytePages(this.#approvalProgramPages)[asNumber(index)] } - clearStateProgramPages(index: StubUint64Compat): bytes { + clearStateProgramPages(index: Uint64Compat): bytes { return combineIntoMaxBytePages(this.#clearStateProgramPages)[asNumber(index)] } - logs(index: StubUint64Compat): bytes { + logs(index: Uint64Compat): bytes { const i = asNumber(index) return this.appLogs[i] ?? lazyContext.getApplicationData(this.appId.id).application.appLogs ?? Bytes() } readonly type: TransactionType.ApplicationCall = TransactionType.ApplicationCall readonly typeBytes: bytes = asUint64Cls(TransactionType.ApplicationCall).toBytes().asAlgoTs() - /* @internal */ + /** @internal */ get appLogs() { return this.#appLogs } - /* @internal */ + /** @internal */ appendLog(value: StubBytesCompat): void { if (this.#appLogs.length + 1 > MAX_ITEMS_IN_LOG) { throw new InternalError(`Too many log calls in program, up to ${MAX_ITEMS_IN_LOG} is allowed`) } this.#appLogs.push(asBytes(value)) } - /* @internal */ + /** @internal */ logArc4ReturnValue(value: unknown): void { this.appendLog(ABI_RETURN_VALUE_LOG_PREFIX.concat(toBytes(value))) } diff --git a/src/impl/txn.ts b/src/impl/txn.ts index f449a89..cae045c 100644 --- a/src/impl/txn.ts +++ b/src/impl/txn.ts @@ -5,9 +5,10 @@ import { InternalError } from '../errors' import { asNumber, asUint64, asUint64Cls } from '../util' import type { StubUint64Compat } from './primitives' +/** @internal */ export const gaid = (a: StubUint64Compat): uint64 => { const group = lazyContext.activeGroup - const transaction = group.getTransaction(a) + const transaction = group.getTransaction(asUint64(a)) if (transaction.type === TransactionType.ApplicationCall) { return transaction.createdApp.id } else if (transaction.type === TransactionType.AssetConfig) { @@ -17,6 +18,7 @@ export const gaid = (a: StubUint64Compat): uint64 => { } } +/** @internal */ export const Txn: typeof op.Txn = { get sender(): Account { return lazyContext.activeGroup.getTransaction().sender diff --git a/src/impl/urange.ts b/src/impl/urange.ts index 6deee53..d661e66 100644 --- a/src/impl/urange.ts +++ b/src/impl/urange.ts @@ -1,6 +1,7 @@ import { asBigInt, asUint64 } from '../util' import type { StubUint64Compat } from './primitives' +/** @internal */ export function* urange(a: StubUint64Compat, b?: StubUint64Compat, c?: StubUint64Compat) { const start = b ? asBigInt(a) : BigInt(0) const end = b ? asBigInt(b) : asBigInt(a) diff --git a/src/impl/voter-params.ts b/src/impl/voter-params.ts index 2f48522..a6499eb 100644 --- a/src/impl/voter-params.ts +++ b/src/impl/voter-params.ts @@ -7,6 +7,7 @@ export class VoterData { balance: uint64 incentiveEligible: boolean + /** @internal */ constructor() { this.balance = 0 this.incentiveEligible = false @@ -18,6 +19,7 @@ const getVoterData = (a: Account | StubUint64Compat): VoterData => { return lazyContext.getVoterData(acct) } +/** @internal */ export const VoterParams: typeof op.VoterParams = { voterBalance: function (a: Account | StubUint64Compat): readonly [uint64, boolean] { const data = getVoterData(a) diff --git a/src/index.ts b/src/index.ts index aa9d422..f04a179 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ export { ApplicationSpy } from './application-spy' export { AssertError, AvmError, CodeError, InternalError, NotImplementedError } from './errors' -export { toExternalValue } from './impl/primitives' export { addEqualityTesters } from './set-up' export { TestExecutionContext } from './test-execution-context' +export { toExternalValue } from './util' diff --git a/src/internal/arc4.ts b/src/internal/arc4.ts index 8c1fa9c..6336db7 100644 --- a/src/internal/arc4.ts +++ b/src/internal/arc4.ts @@ -1,6 +1,10 @@ +/** @internal */ export * from '@algorandfoundation/algorand-typescript/arc4' +/** @internal */ export { abiCall, compileArc4 } from '../impl/c2c' +/** @internal */ export { abimethod, baremethod, Contract } from '../impl/contract' +/** @internal */ export { Address, arc4EncodedLength, @@ -21,4 +25,5 @@ export { UFixed, Uint, } from '../impl/encoded-types' +/** @internal */ export { methodSelector } from '../impl/method-selector' diff --git a/src/internal/index.ts b/src/internal/index.ts index 4a8878a..3ea1c66 100644 --- a/src/internal/index.ts +++ b/src/internal/index.ts @@ -1,21 +1,40 @@ +/** @internal */ export * from '@algorandfoundation/algorand-typescript' +/** @internal */ export { BaseContract, contract } from '../impl/base-contract' +/** @internal */ export { clone } from '../impl/clone' +/** @internal */ export { compile } from '../impl/compiled' +/** @internal */ export { abimethod, baremethod, Contract } from '../impl/contract' +/** @internal */ export { emit } from '../impl/emit' +/** @internal */ export { ensureBudget } from '../impl/ensure-budget' +/** @internal */ export { Global } from '../impl/global' +/** @internal */ export { log } from '../impl/log' +/** @internal */ export { assertMatch, match } from '../impl/match' +/** @internal */ export { BigUint, Bytes, Uint64 } from '../impl/primitives' +/** @internal */ export { Account, Application, Asset } from '../impl/reference' +/** @internal */ export { Box, BoxMap, BoxRef, GlobalState, LocalState } from '../impl/state' +/** @internal */ export { TemplateVar } from '../impl/template-var' +/** @internal */ export { Txn } from '../impl/txn' +/** @internal */ export { urange } from '../impl/urange' +/** @internal */ export { assert, err } from '../util' +/** @internal */ export * as arc4 from './arc4' +/** @internal */ export * as op from './op' import { ApplicationCallTxn, @@ -26,6 +45,7 @@ import { PaymentTxn, Transaction, } from '../impl/gtxn' +/** @internal */ export const gtxn = { Transaction, PaymentTxn, @@ -37,6 +57,7 @@ export const gtxn = { } import { applicationCall, assetConfig, assetFreeze, assetTransfer, keyRegistration, payment, submitGroup } from '../impl/inner-transactions' +/** @internal */ export const itxn = { submitGroup, payment, @@ -47,4 +68,5 @@ export const itxn = { applicationCall, } +/** @internal */ export { itxnCompose } from '../impl/itxn-compose' diff --git a/src/internal/op.ts b/src/internal/op.ts index b1fe52d..67dec9c 100644 --- a/src/internal/op.ts +++ b/src/internal/op.ts @@ -1,12 +1,22 @@ +/** @internal */ export * from '@algorandfoundation/algorand-typescript/op' +/** @internal */ export { AcctParams, appOptedIn, balance, minBalance } from '../impl/acct-params' +/** @internal */ export { AppGlobal } from '../impl/app-global' +/** @internal */ export { AppLocal } from '../impl/app-local' +/** @internal */ export { AppParams } from '../impl/app-params' +/** @internal */ export { AssetHolding } from '../impl/asset-holding' +/** @internal */ export { AssetParams } from '../impl/asset-params' +/** @internal */ export { Block } from '../impl/block' +/** @internal */ export { Box } from '../impl/box' +/** @internal */ export { ecdsaPkDecompress, ecdsaPkRecover, @@ -21,11 +31,17 @@ export { sha512_256, vrfVerify, } from '../impl/crypto' +/** @internal */ export { Global } from '../impl/global' +/** @internal */ export { GTxn } from '../impl/gtxn' +/** @internal */ export { GITxn, ITxn, ITxnCreate } from '../impl/itxn' +/** @internal */ export { arg } from '../impl/logicSigArg' +/** @internal */ export { onlineStake } from '../impl/online-stake' +/** @internal */ export { addw, base64Decode, @@ -57,6 +73,9 @@ export { sqrt, substring, } from '../impl/pure' +/** @internal */ export { gloadBytes, gloadUint64, Scratch } from '../impl/scratch' +/** @internal */ export { gaid, Txn } from '../impl/txn' +/** @internal */ export { VoterParams } from '../impl/voter-params' diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 13064e8..b3f32ad 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -9,9 +9,12 @@ import { AccountCls } from './impl/reference' import { nameOfType, type DeliberateAny } from './typescript-helpers' import { flattenAsBytes } from './util' +/** @internal */ export { attachAbiMetadata } from './abi-metadata' +/** @internal */ export { FixedBytes } from './impl/primitives' +/** @internal */ export function switchableValue(x: unknown): bigint | string | boolean { if (typeof x === 'boolean') return x if (typeof x === 'bigint') return x @@ -31,6 +34,7 @@ function tryGetBigInt(value: unknown): bigint | undefined { return undefined } +/** @internal */ export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { if (left instanceof ARC4Encoded && right instanceof ARC4Encoded) { return arc4EncodedOp(left, right, op) @@ -68,6 +72,7 @@ export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { return defaultBinaryOp(left, right, op) } +/** @internal */ export function unaryOp(operand: unknown, op: UnaryOps) { if (operand instanceof Uint64Cls) { return uint64UnaryOp(operand, op) @@ -316,11 +321,13 @@ function defaultUnaryOp(_operand: DeliberateAny, op: UnaryOps): DeliberateAny { } const genericTypeMap = new WeakMap() +/** @internal */ export function captureGenericTypeInfo(target: DeliberateAny, t: string) { genericTypeMap.set(target, JSON.parse(t)) return target } +/** @internal */ export function getGenericTypeInfo(target: DeliberateAny): TypeInfo | undefined { return genericTypeMap.get(target) } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 608b945..fb7783f 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,3 +1,4 @@ +import type { BaseContract as BaseContractType } from '@algorandfoundation/algorand-typescript' import { OnCompleteAction, type Account, @@ -89,7 +90,9 @@ const extractStates = (contract: BaseContract, contractOptions: ContractOptionsP const getUint8 = (value: number) => new Uint({ name: 'Uint<8>', genericArgs: [{ name: '8' }] }, value) -/** @ignore */ +/** + * @internal + */ export const extractArraysFromArgs = ( app: Application, methodSelector: Uint8Array, @@ -171,7 +174,7 @@ export class ContractContext { * const ctx = new TestExecutionContext(); * const contract = ctx.contract.create(MyContract); */ - create(type: IConstructor, ...args: DeliberateAny[]): T { + create(type: IConstructor, ...args: DeliberateAny[]): T { const proxy = new Proxy(type, this.getContractProxyHandler(this.isArc4(type))) return new proxy(...args) } @@ -211,6 +214,9 @@ export class ContractContext { return txns } + /** + * @internal + */ private isArc4(type: IConstructor): boolean { const result = (type as DeliberateAny as typeof BaseContract).isArc4 if (result !== undefined && result !== null) { @@ -230,6 +236,9 @@ export class ContractContext { return this.isArc4(proto) } + /** + * @internal + */ private getContractProxyHandler(isArc4: boolean): ProxyHandler> { const onConstructed = (application: Application, instance: T, conrtactOptions: ContractOptionsParameter | undefined) => { const states = extractStates(instance, conrtactOptions) diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index ed02fe9..ede9f37 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -4,8 +4,10 @@ import type { Asset as AssetType, BaseContract, bytes, + BytesCompat, LocalStateForAccount, uint64, + Uint64Compat, } from '@algorandfoundation/algorand-typescript' import { AccountMap, Uint64Map } from '../collections/custom-key-map' import { MAX_UINT64 } from '../constants' @@ -13,7 +15,7 @@ import { InternalError } from '../errors' import { BlockData } from '../impl/block' import { toBytes } from '../impl/encoded-types' import { GlobalData } from '../impl/global' -import { Uint64Cls, type StubBytesCompat, type StubUint64Compat } from '../impl/primitives' +import { Uint64Cls } from '../impl/primitives' import type { AssetData } from '../impl/reference' import { AccountCls, @@ -31,14 +33,23 @@ import type { PickPartial } from '../typescript-helpers' import { asBigInt, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, asUint8Array, iterBigInt } from '../util' export class LedgerContext { + /** @internal */ appIdIter = iterBigInt(1001n, MAX_UINT64) + /** @internal */ assetIdIter = iterBigInt(1001n, MAX_UINT64) + /** @internal */ applicationDataMap = new Uint64Map() + /** @internal */ appIdContractMap = new Uint64Map() + /** @internal */ accountDataMap = new AccountMap() + /** @internal */ assetDataMap = new Uint64Map() + /** @internal */ voterDataMap = new AccountMap() + /** @internal */ blocks = new Uint64Map() + /** @internal */ globalData = new GlobalData() onlineStake = 0 @@ -48,7 +59,7 @@ export class LedgerContext { * @param appId - The application ID. * @param contract - The contract to add. */ - addAppIdContractMap(appId: StubUint64Compat, contract: BaseContract): void { + addAppIdContractMap(appId: Uint64Compat, contract: BaseContract): void { this.appIdContractMap.set(appId, contract) } @@ -57,8 +68,8 @@ export class LedgerContext { * @param address - The account address. * @returns The account. */ - getAccount(address: AccountType | StubBytesCompat): AccountType { - return new AccountCls(address instanceof AccountCls ? address.bytes : asBytes(address as StubBytesCompat)) + getAccount(address: AccountType | BytesCompat): AccountType { + return new AccountCls(address instanceof AccountCls ? address.bytes : asBytes(address as BytesCompat)) } /** @@ -67,7 +78,7 @@ export class LedgerContext { * @returns The asset. * @throws If the asset is unknown. */ - getAsset(assetId: StubUint64Compat): AssetType { + getAsset(assetId: Uint64Compat): AssetType { if (this.assetDataMap.has(assetId)) { return Asset(asUint64(assetId)) } @@ -80,7 +91,7 @@ export class LedgerContext { * @returns The application. * @throws If the application is unknown. */ - getApplication(applicationId: StubUint64Compat): ApplicationType { + getApplication(applicationId: Uint64Compat): ApplicationType { if (this.applicationDataMap.has(applicationId)) { return Application(asUint64(applicationId)) } @@ -139,8 +150,8 @@ export class LedgerContext { * @param balance * @param frozen */ - updateAssetHolding(account: AccountType, assetId: StubUint64Compat | AssetType, balance?: StubUint64Compat, frozen?: boolean): void { - const id = asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as AssetType).id) + updateAssetHolding(account: AccountType, assetId: Uint64Compat | AssetType, balance?: Uint64Compat, frozen?: boolean): void { + const id = (asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as AssetType).id)).asAlgoTs() const accountData = this.accountDataMap.get(account)! const asset = this.assetDataMap.get(id)! const holding = accountData.optedAssets.get(id) ?? new AssetHolding(0n, asset.defaultFrozen) @@ -199,7 +210,7 @@ export class LedgerContext { /** * Patches asset data with the provided partial data. - * @param account - The asset. + * @param asset - The asset. * @param data - The partial asset data. */ patchAssetData(asset: AssetType, data: Partial) { @@ -228,7 +239,7 @@ export class LedgerContext { * @param index - The block index. * @param data - The partial block data. */ - patchBlockData(index: StubUint64Compat, data: Partial): void { + patchBlockData(index: Uint64Compat, data: Partial): void { const i = asUint64(index) const blockData = this.blocks.get(i) ?? new BlockData() this.blocks.set(i, { @@ -243,7 +254,7 @@ export class LedgerContext { * @returns The block data. * @throws If the block is not set. */ - getBlockData(index: StubUint64Compat): BlockData { + getBlockData(index: Uint64Compat): BlockData { const i = asBigInt(index) if (this.blocks.has(i)) { return this.blocks.get(i)! @@ -257,7 +268,7 @@ export class LedgerContext { * @param key - The key. * @returns The global state and a boolean indicating if it was found. */ - getGlobalState(app: ApplicationType | BaseContract, key: StubBytesCompat): [GlobalStateCls, true] | [undefined, false] { + getGlobalState(app: ApplicationType | BaseContract, key: BytesCompat): [GlobalStateCls, true] | [undefined, false] { const appId = this.getAppId(app) const appData = this.applicationDataMap.get(appId) if (!appData?.application.globalStates.has(key)) { @@ -272,7 +283,7 @@ export class LedgerContext { * @param key - The key. * @param value - The value (optional). */ - setGlobalState(app: ApplicationType | BaseContract, key: StubBytesCompat, value: StubUint64Compat | StubBytesCompat | undefined): void { + setGlobalState(app: ApplicationType | BaseContract, key: BytesCompat, value: Uint64Compat | BytesCompat | undefined): void { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) const globalState = appData.application.globalStates.get(key) @@ -295,9 +306,9 @@ export class LedgerContext { getLocalState( app: ApplicationType | BaseContract | uint64, account: AccountType, - key: StubBytesCompat, + key: BytesCompat, ): [LocalStateForAccount, true] | [undefined, false] { - const appId = app instanceof Uint64Cls ? app : this.getAppId(app as ApplicationType | BaseContract) + const appId = app instanceof Uint64Cls ? app.asAlgoTs() : this.getAppId(app as ApplicationType | BaseContract) const appData = this.applicationDataMap.get(appId) if (!appData?.application.localStates.has(key)) { return [undefined, false] @@ -314,8 +325,8 @@ export class LedgerContext { * @param key - The key. * @param value - The value (optional). */ - setLocalState(app: ApplicationType | BaseContract | uint64, account: AccountType, key: StubBytesCompat, value: T | undefined): void { - const appId = app instanceof Uint64Cls ? app : this.getAppId(app as ApplicationType | BaseContract) + setLocalState(app: ApplicationType | BaseContract | uint64, account: AccountType, key: BytesCompat, value: T | undefined): void { + const appId = app instanceof Uint64Cls ? app.asAlgoTs() : this.getAppId(app as ApplicationType | BaseContract) const appData = this.applicationDataMap.getOrFail(appId) if (!appData.application.localStateMaps.has(key)) { appData.application.localStateMaps.set(key, new AccountMap()) @@ -338,7 +349,7 @@ export class LedgerContext { * @param key - The key. * @returns The box data. */ - getBox(app: ApplicationType | BaseContract, key: StubBytesCompat): Uint8Array { + getBox(app: ApplicationType | BaseContract, key: BytesCompat): Uint8Array { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) const materialised = appData.application.materialisedBoxes.get(key) @@ -355,7 +366,7 @@ export class LedgerContext { * @param key - The key. * @returns The materialised box data if exists or undefined. */ - getMaterialisedBox(app: ApplicationType | BaseContract, key: StubBytesCompat): T | undefined { + getMaterialisedBox(app: ApplicationType | BaseContract, key: BytesCompat): T | undefined { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) return appData.application.materialisedBoxes.get(key) as T | undefined @@ -367,7 +378,7 @@ export class LedgerContext { * @param key - The key. * @param value - The box data. */ - setBox(app: ApplicationType | BaseContract, key: StubBytesCompat, value: StubBytesCompat | Uint8Array): void { + setBox(app: ApplicationType | BaseContract, key: BytesCompat, value: BytesCompat | Uint8Array): void { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) const uint8ArrayValue = value instanceof Uint8Array ? value : asUint8Array(value) @@ -383,7 +394,7 @@ export class LedgerContext { * @param key - The key. * @param value - The box data. */ - setMatrialisedBox(app: ApplicationType | BaseContract, key: StubBytesCompat, value: TValue | undefined): void { + setMaterialisedBox(app: ApplicationType | BaseContract, key: BytesCompat, value: TValue | undefined): void { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) appData.application.materialisedBoxes.set(key, value) @@ -395,7 +406,7 @@ export class LedgerContext { * @param key - The key. * @returns True if the box was deleted, false otherwise. */ - deleteBox(app: ApplicationType | BaseContract, key: StubBytesCompat): boolean { + deleteBox(app: ApplicationType | BaseContract, key: BytesCompat): boolean { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) appData.application.materialisedBoxes.delete(key) @@ -408,12 +419,13 @@ export class LedgerContext { * @param key - The key. * @returns True if the box exists, false otherwise. */ - boxExists(app: ApplicationType | BaseContract, key: StubBytesCompat): boolean { + boxExists(app: ApplicationType | BaseContract, key: BytesCompat): boolean { const appId = this.getAppId(app) const appData = this.applicationDataMap.getOrFail(appId) return appData.application.boxes.has(key) } + /** @internal */ private getAppId(app: ApplicationType | BaseContract): uint64 { return app instanceof ApplicationCls ? app.id : this.getApplicationForContract(app as BaseContract).id } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index ca14585..93ee04d 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,4 +1,4 @@ -import type { bytes, Contract, uint64 } from '@algorandfoundation/algorand-typescript' +import type { bytes, Contract, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' import { OnCompleteAction, TransactionType } from '@algorandfoundation/algorand-typescript' import { getContractAbiMetadata, type AbiMetadata } from '../abi-metadata' import { TRANSACTION_GROUP_MAX_SIZE } from '../constants' @@ -17,7 +17,7 @@ import type { } from '../impl/inner-transactions' import { ApplicationCallInnerTxnContext, createInnerTxn, ItxnParams } from '../impl/inner-transactions' import type { InnerTxn, InnerTxnFields } from '../impl/itxn' -import type { StubBytesCompat, StubUint64Compat } from '../impl/primitives' +import type { StubBytesCompat } from '../impl/primitives' import type { AllTransactionFields, ApplicationCallTransaction, @@ -57,11 +57,17 @@ interface ExecutionScope { * Represents a deferred application call. */ export class DeferredAppCall { + /** @internal */ constructor( + /** @internal */ private readonly appId: uint64, + /** @internal */ readonly txns: Transaction[], + /** @internal */ private readonly method: (...args: TParams) => TReturn, + /** @internal */ private readonly abiMetadata: AbiMetadata, + /** @internal */ private readonly args: TParams, ) {} @@ -231,12 +237,15 @@ export class TransactionContext { * Represents a group of transactions. */ export class TransactionGroup { - activeTransactionIndex: number latestTimestamp: number transactions: Transaction[] itxnGroups: ItxnGroup[] = [] + /** @internal */ + activeTransactionIndex: number + /** @internal */ constructingItxnGroup: InnerTxnFields[] = [] + /** @internal */ constructor(transactions: Transaction[], activeTransactionIndex?: number) { this.latestTimestamp = Date.now() if (transactions.length > TRANSACTION_GROUP_MAX_SIZE) { @@ -290,7 +299,7 @@ export class TransactionGroup { * @param index The index of the scratch slot. * @returns The scratch slot value. */ - getScratchSlot(index: StubUint64Compat): bytes | uint64 { + getScratchSlot(index: Uint64Compat): bytes | uint64 { return this.activeTransaction.getScratchSlot(index) } @@ -384,7 +393,7 @@ export class TransactionGroup { * @returns The inner transaction group. * @throws If the index is invalid or there are no previous inner transactions. */ - getItxnGroup(index?: StubUint64Compat): ItxnGroup { + getItxnGroup(index?: Uint64Compat): ItxnGroup { const i = index !== undefined ? asNumber(index) : undefined invariant(this.itxnGroups.length > 0, 'no previous inner transactions') @@ -402,7 +411,7 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The application transaction. */ - getApplicationCallTransaction(index?: StubUint64Compat): ApplicationCallTransaction { + getApplicationCallTransaction(index?: Uint64Compat): ApplicationCallTransaction { return this._getTransaction({ type: TransactionType.ApplicationCall, index }) as ApplicationCallTransaction } @@ -411,7 +420,7 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The asset configuration transaction. */ - getAssetConfigTransaction(index?: StubUint64Compat): AssetConfigTransaction { + getAssetConfigTransaction(index?: Uint64Compat): AssetConfigTransaction { return this._getTransaction({ type: TransactionType.AssetConfig, index }) as AssetConfigTransaction } @@ -420,7 +429,7 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The asset transfer transaction. */ - getAssetTransferTransaction(index?: StubUint64Compat): AssetTransferTransaction { + getAssetTransferTransaction(index?: Uint64Compat): AssetTransferTransaction { return this._getTransaction({ type: TransactionType.AssetTransfer, index }) as AssetTransferTransaction } @@ -429,7 +438,7 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The asset freeze transaction. */ - getAssetFreezeTransaction(index?: StubUint64Compat): AssetFreezeTransaction { + getAssetFreezeTransaction(index?: Uint64Compat): AssetFreezeTransaction { return this._getTransaction({ type: TransactionType.AssetFreeze, index }) as AssetFreezeTransaction } @@ -438,7 +447,7 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The key registration transaction. */ - getKeyRegistrationTransaction(index?: StubUint64Compat): KeyRegistrationTransaction { + getKeyRegistrationTransaction(index?: Uint64Compat): KeyRegistrationTransaction { return this._getTransaction({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationTransaction } @@ -447,7 +456,7 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The payment transaction. */ - getPaymentTransaction(index?: StubUint64Compat): PaymentTransaction { + getPaymentTransaction(index?: Uint64Compat): PaymentTransaction { return this._getTransaction({ type: TransactionType.Payment, index }) as PaymentTransaction } @@ -456,10 +465,11 @@ export class TransactionGroup { * @param index The index of the transaction. * @returns The transaction. */ - getTransaction(index?: StubUint64Compat): Transaction { + getTransaction(index?: Uint64Compat): Transaction { return this._getTransaction({ index }) } - private _getTransaction({ type, index }: { type?: TransactionType; index?: StubUint64Compat }) { + /** @internal */ + private _getTransaction({ type, index }: { type?: TransactionType; index?: Uint64Compat }) { const i = index !== undefined ? asNumber(index) : undefined if (i !== undefined && i >= lazyContext.activeGroup.transactions.length) { throw new InternalError('Invalid group index') @@ -495,6 +505,7 @@ export class TransactionGroup { */ export class ItxnGroup { itxns: InnerTxn[] = [] + /** @internal */ constructor(itxns: InnerTxn[]) { this.itxns = itxns } @@ -504,7 +515,7 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The application inner transaction. */ - getApplicationCallInnerTxn(index?: StubUint64Compat): ApplicationCallInnerTxn { + getApplicationCallInnerTxn(index?: Uint64Compat): ApplicationCallInnerTxn { return this._getInnerTxn({ type: TransactionType.ApplicationCall, index }) as ApplicationCallInnerTxn } @@ -513,7 +524,7 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The asset configuration inner transaction. */ - getAssetConfigInnerTxn(index?: StubUint64Compat): AssetConfigInnerTxn { + getAssetConfigInnerTxn(index?: Uint64Compat): AssetConfigInnerTxn { return this._getInnerTxn({ type: TransactionType.AssetConfig, index }) as AssetConfigInnerTxn } @@ -522,7 +533,7 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The asset transfer inner transaction. */ - getAssetTransferInnerTxn(index?: StubUint64Compat): AssetTransferInnerTxn { + getAssetTransferInnerTxn(index?: Uint64Compat): AssetTransferInnerTxn { return this._getInnerTxn({ type: TransactionType.AssetTransfer, index }) as AssetTransferInnerTxn } @@ -531,7 +542,7 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The asset freeze inner transaction. */ - getAssetFreezeInnerTxn(index?: StubUint64Compat): AssetFreezeInnerTxn { + getAssetFreezeInnerTxn(index?: Uint64Compat): AssetFreezeInnerTxn { return this._getInnerTxn({ type: TransactionType.AssetFreeze, index }) as AssetFreezeInnerTxn } @@ -540,7 +551,7 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The key registration inner transaction. */ - getKeyRegistrationInnerTxn(index?: StubUint64Compat): KeyRegistrationInnerTxn { + getKeyRegistrationInnerTxn(index?: Uint64Compat): KeyRegistrationInnerTxn { return this._getInnerTxn({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationInnerTxn } @@ -549,7 +560,7 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The payment inner transaction. */ - getPaymentInnerTxn(index?: StubUint64Compat): PaymentInnerTxn { + getPaymentInnerTxn(index?: Uint64Compat): PaymentInnerTxn { return this._getInnerTxn({ type: TransactionType.Payment, index }) as PaymentInnerTxn } @@ -558,11 +569,12 @@ export class ItxnGroup { * @param index The index of the transaction. * @returns The inner transaction. */ - getInnerTxn(index?: StubUint64Compat): InnerTxn { + getInnerTxn(index?: Uint64Compat): InnerTxn { return this._getInnerTxn({ index }) } - private _getInnerTxn({ type, index }: { type?: TransactionType; index?: StubUint64Compat }) { + /** @internal */ + private _getInnerTxn({ type, index }: { type?: TransactionType; index?: Uint64Compat }) { invariant(this.itxns.length > 0, 'no previous inner transactions') const i = index !== undefined ? asNumber(index) : undefined if (i !== undefined && i >= this.itxns.length) { diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 56f244c..87e7a0c 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -182,7 +182,7 @@ export class TestExecutionContext { } } - /* @internal */ + /** @internal */ notifyApplicationSpies(itxn: ApplicationCallInnerTxnContext) { for (const spy of this.#applicationSpies) { spy.notify(itxn) diff --git a/src/test-transformer/errors.ts b/src/test-transformer/errors.ts index 5f2f7d7..5a3f9f5 100644 --- a/src/test-transformer/errors.ts +++ b/src/test-transformer/errors.ts @@ -1,3 +1,4 @@ +/** @internal */ export class TransformerError extends Error { constructor(message: string) { super(message) diff --git a/src/test-transformer/helpers.ts b/src/test-transformer/helpers.ts index 51b1716..ef70c03 100644 --- a/src/test-transformer/helpers.ts +++ b/src/test-transformer/helpers.ts @@ -1,6 +1,7 @@ import ts from 'typescript' import { TransformerError } from './errors' +/** @internal */ export const getPropertyNameAsString = (name: ts.PropertyName): ts.Identifier | ts.StringLiteral | ts.NoSubstitutionTemplateLiteral => { if (ts.isStringLiteralLike(name)) { return name @@ -11,4 +12,5 @@ export const getPropertyNameAsString = (name: ts.PropertyName): ts.Identifier | throw new TransformerError(`Node ${name.kind} cannot be converted to a static string`) } +/** @internal */ export const trimGenericTypeName = (typeName: string) => typeName.replace(/<.*>/, '') diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 63e7fb6..7a3b998 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -5,6 +5,7 @@ import type { DeliberateAny } from '../typescript-helpers' import { getPropertyNameAsString, trimGenericTypeName } from './helpers' const factory = ts.factory +/** @internal */ export const nodeFactory = { importHelpers(testingPackageName: string) { return [ diff --git a/src/test-transformer/program-factory.ts b/src/test-transformer/program-factory.ts index c9ceda7..d00fe65 100644 --- a/src/test-transformer/program-factory.ts +++ b/src/test-transformer/program-factory.ts @@ -6,11 +6,13 @@ export interface TransformerConfig { includeExt: string[] testingPackageName: string } +/** @internal */ export const defaultTransformerConfig: TransformerConfig = { includeExt: ['.algo.ts', '.algo.spec.ts', '.algo.test.ts'], testingPackageName: '@algorandfoundation/algorand-typescript-testing', } +/** @internal */ export function programFactory(config: TransformerConfig, program: ts.Program): ts.TransformerFactory { registerPTypes(typeRegistry) return (context) => { diff --git a/src/test-transformer/supported-binary-op-string.ts b/src/test-transformer/supported-binary-op-string.ts index 7f51847..555cecf 100644 --- a/src/test-transformer/supported-binary-op-string.ts +++ b/src/test-transformer/supported-binary-op-string.ts @@ -1,6 +1,7 @@ import type { BinaryOperator, PrefixUnaryOperator } from 'typescript' import ts from 'typescript' +/** @internal */ export function supportedBinaryOpString(x: BinaryOperator): string | undefined { switch (x) { case ts.SyntaxKind.MinusToken: @@ -60,6 +61,7 @@ export function supportedBinaryOpString(x: BinaryOperator): string | undefined { } } +/** @internal */ export function supportedAugmentedAssignmentBinaryOpString(x: BinaryOperator): string | undefined { switch (x) { case ts.SyntaxKind.PlusEqualsToken: @@ -79,6 +81,7 @@ export function supportedAugmentedAssignmentBinaryOpString(x: BinaryOperator): s } } +/** @internal */ export function supportedPrefixUnaryOpString(x: PrefixUnaryOperator): string | undefined { switch (x) { case ts.SyntaxKind.TildeToken: diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 482c420..02aca3d 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -22,6 +22,13 @@ const algotsModulePaths = [ '/puya-ts/packages/algo-ts/', `${path.sep}puya-ts${path.sep}packages${path.sep}algo-ts${path.sep}`, ] +const algotsTestingModulePaths = (testingPackageName: string) => [ + testingPackageName, + `${path.sep}algorand-typescript-testing${path.sep}src${path.sep}`, + `${path.sep}algorand-typescript-testing${path.sep}dist${path.sep}`, +] + +const testingExamplePath = `${path.sep}algorand-typescript-testing${path.sep}examples${path.sep}` type VisitorHelper = { additionalStatements: ts.Statement[] @@ -29,8 +36,10 @@ type VisitorHelper = { resolveTypeParameters(node: ts.CallExpression): ptypes.PType[] sourceLocation(node: ts.Node): SourceLocation tryGetSymbol(node: ts.Node): ts.Symbol | undefined + getConfig(): TransformerConfig } +/** @internal */ export class SourceFileVisitor { private helper: VisitorHelper @@ -38,7 +47,7 @@ export class SourceFileVisitor { private context: ts.TransformationContext, private sourceFile: ts.SourceFile, program: ts.Program, - private config: TransformerConfig, + config: TransformerConfig, ) { const typeChecker = program.getTypeChecker() const loggingContext = LoggingContext.create() @@ -74,13 +83,16 @@ export class SourceFileVisitor { return SourceLocation.None } }, + getConfig(): TransformerConfig { + return config + }, } } public result(): ts.SourceFile { const updatedSourceFile = ts.visitNode(this.sourceFile, this.visit) as ts.SourceFile return factory.updateSourceFile(updatedSourceFile, [ - ...nodeFactory.importHelpers(this.config.testingPackageName), + ...nodeFactory.importHelpers(this.helper.getConfig().testingPackageName), ...updatedSourceFile.statements, ...this.helper.additionalStatements, ]) @@ -88,7 +100,7 @@ export class SourceFileVisitor { private visit = (node: ts.Node): ts.Node => { if (ts.isImportDeclaration(node)) { - return new ImportDeclarationVisitor(this.context, this.helper, this.config, node).result() + return new ImportDeclarationVisitor(node, this.helper).result() } if (ts.isFunctionLike(node)) { return new FunctionLikeDecVisitor(this.context, this.helper, node).result() @@ -109,10 +121,8 @@ export class SourceFileVisitor { class ImportDeclarationVisitor { constructor( - private context: ts.TransformationContext, - private helper: VisitorHelper, - private config: TransformerConfig, private declarationNode: ts.ImportDeclaration, + private helper: VisitorHelper, ) {} public result(): ts.ImportDeclaration { @@ -132,7 +142,7 @@ class ImportDeclarationVisitor { : this.declarationNode.importClause, factory.createStringLiteral( moduleSpecifier - .replace(algotsModuleSpecifier, testingInternalModuleSpecifier(this.config.testingPackageName)) + .replace(algotsModuleSpecifier, testingInternalModuleSpecifier(this.helper.getConfig().testingPackageName)) .replace(/^("|')/, '') .replace(/("|')$/, ''), ), @@ -154,7 +164,9 @@ class ExpressionVisitor { } private visit = (node: ts.Node): ts.Node => { - handleTypeInfoCaputre: if (ts.isCallExpression(node) || ts.isNewExpression(node)) { + handleTypeInfoCapture: if (ts.isCallExpression(node) || ts.isNewExpression(node)) { + if (!tryGetAlgoTsSymbolName(node.expression, this.helper)) break handleTypeInfoCapture + let type = this.helper.resolveType(node) // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState @@ -180,7 +192,7 @@ class ExpressionVisitor { // the nodes which have been created or updated by the node factory will not have source location, // and we do not need to process them further const sourceLocation = this.helper.sourceLocation(updatedNode) - if (sourceLocation === SourceLocation.None) break handleTypeInfoCaputre + if (sourceLocation === SourceLocation.None) break handleTypeInfoCapture if ( isCallingEmit(stubbedFunctionName) || @@ -518,12 +530,20 @@ const tryGetStubbedFunctionName = (node: ts.CallExpression, helper: VisitorHelpe } const tryGetAlgoTsSymbolName = (node: ts.Node, helper: VisitorHelper): string | undefined => { - const s = helper.tryGetSymbol(node) - if (s) { - const sourceFileName = s.valueDeclaration?.getSourceFile().fileName - if (sourceFileName && !algotsModulePaths.some((s) => sourceFileName.includes(s))) return undefined - } - return s?.getName() ?? (ts.isMemberName(node) ? node.text : node.getText()) + const symbol = helper.tryGetSymbol(node) + if (!symbol) return undefined + + const sourceFileName = symbol.valueDeclaration?.getSourceFile().fileName + if (!sourceFileName) return undefined + + // If the symbol is from algorand-typescript package or testing example path, return its name + if (algotsModulePaths.some((path) => sourceFileName.includes(path)) || sourceFileName.includes(testingExamplePath)) + return symbol.getName() + + // If the symbol is from algorand-typescript-testing package, return undefined as they do not need to be processed + if (algotsTestingModulePaths(helper.getConfig().testingPackageName).some((path) => sourceFileName.includes(path))) return undefined + + return symbol.getName() } const isCallingDecodeArc4 = (functionName: string | undefined): boolean => 'decodeArc4' === (functionName ?? '') diff --git a/src/util.ts b/src/util.ts index 400335c..41c006e 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,4 @@ -import type { bytes } from '@algorandfoundation/algorand-typescript' +import type { biguint, bytes, uint64 } from '@algorandfoundation/algorand-typescript' import { randomBytes } from 'crypto' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' import { AssertError, AvmError, InternalError } from './errors' @@ -6,31 +6,82 @@ import type { StubBigUintCompat, StubBytesCompat, StubUint64Compat } from './imp import { BigUintCls, Bytes, BytesCls, Uint64Cls } from './impl/primitives' import type { DeliberateAny } from './typescript-helpers' +/** + * Converts internal Algorand type representations to their external primitive values. + * + * @overload + * @param {uint64} val - A uint64 value to convert + * @returns {bigint} The uint64 value as a bigint + * + * @overload + * @param {biguint} val - A biguint value to convert + * @returns {bigint} The biguint value as a bigint + * + * @overload + * @param {bytes} val - A bytes value to convert + * @returns {Uint8Array} The bytes value as a Uint8Array + * + * @overload + * @param {string} val - A string value to pass through + * @returns {string} The original string value unchanged + * + * @example + * ```ts + * const uint64Val = Uint64(123n) + * toExternalValue(uint64Val) // returns 123n + * + * const bytesVal = Bytes.fromBase64("SGVsbG8="); + * toExternalValue(bytesVal) // returns Uint8Array([72, 101, 108, 108, 111]) + * ``` + */ +export function toExternalValue(val: uint64): bigint +export function toExternalValue(val: biguint): bigint +export function toExternalValue(val: bytes): Uint8Array +export function toExternalValue(val: string): string +export function toExternalValue(val: uint64 | biguint | bytes | string) { + const instance = val as unknown + if (instance instanceof BytesCls) return instance.asUint8Array() + if (instance instanceof Uint64Cls) return instance.asBigInt() + if (instance instanceof BigUintCls) return instance.asBigInt() + if (typeof val === 'string') return val +} + +/** @internal */ export function* iterBigInt(start: bigint, end: bigint): Generator { for (let i = start; i < end; i++) { yield BigInt(i) } } +/** @internal */ export const asBigInt = (v: StubUint64Compat): bigint => asUint64Cls(v).asBigInt() +/** @internal */ export const asNumber = (v: StubUint64Compat): number => asUint64Cls(v).asNumber() +/** @internal */ export const asUint64Cls = (val: StubUint64Compat) => Uint64Cls.fromCompat(val) +/** @internal */ export const asBigUintCls = (val: StubBigUintCompat | Uint8Array) => BigUintCls.fromCompat(val instanceof Uint8Array ? asBytes(val) : Array.isArray(val) ? asBytes(new Uint8Array(val)) : val) +/** @internal */ export const asBytesCls = (val: StubBytesCompat | Uint8Array) => BytesCls.fromCompat(val) +/** @internal */ export const asUint64 = (val: StubUint64Compat) => asUint64Cls(val).asAlgoTs() +/** @internal */ export const asBigUint = (val: StubBigUintCompat | Uint8Array) => asBigUintCls(val).asAlgoTs() +/** @internal */ export const asBytes = (val: StubBytesCompat | Uint8Array) => asBytesCls(val).asAlgoTs() +/** @internal */ export const asUint8Array = (val: StubBytesCompat | Uint8Array) => asBytesCls(val).asUint8Array() +/** @internal */ export const asMaybeUint64Cls = (val: DeliberateAny, throwsOverflow: boolean = true) => { try { return Uint64Cls.fromCompat(val) @@ -46,6 +97,7 @@ export const asMaybeUint64Cls = (val: DeliberateAny, throwsOverflow: boolean = t return undefined } +/** @internal */ export const asMaybeBigUintCls = (val: DeliberateAny) => { try { return BigUintCls.fromCompat(val) @@ -58,6 +110,7 @@ export const asMaybeBigUintCls = (val: DeliberateAny) => { } return undefined } +/** @internal */ export const asMaybeBytesCls = (val: DeliberateAny) => { try { return BytesCls.fromCompat(val) @@ -71,13 +124,16 @@ export const asMaybeBytesCls = (val: DeliberateAny) => { return undefined } +/** @internal */ export const binaryStringToBytes = (s: string): BytesCls => BytesCls.fromCompat(new Uint8Array(s.match(/.{1,8}/g)!.map((x) => parseInt(x, 2)))) +/** @internal */ export const getRandomNumber = (min: number, max: number): number => { return Math.floor(Math.random() * (max - min + 1)) + min } +/** @internal */ export const getRandomBigInt = (min: number | bigint, max: number | bigint): bigint => { const bigIntMin = BigInt(min) const bigIntMax = BigInt(max) @@ -87,14 +143,17 @@ export const getRandomBigInt = (min: number | bigint, max: number | bigint): big return (randomValue % (bigIntMax - bigIntMin)) + bigIntMin } +/** @internal */ export const getRandomBytes = (length: number): BytesCls => asBytesCls(Bytes(randomBytes(length))) +/** @internal */ export const flattenAsBytes = (arr: StubBytesCompat | StubBytesCompat[]): bytes => { return (Array.isArray(arr) ? arr : [arr]).map((x) => asBytes(x)).reduce((acc, x) => acc.concat(x), Bytes()) } const NoValue = Symbol('no-value') type LazyInstance = () => T +/** @internal */ export const Lazy = (factory: () => T): LazyInstance => { let val: T | typeof NoValue = NoValue @@ -108,6 +167,7 @@ export const Lazy = (factory: () => T): LazyInstance => { const ObjectReferenceSymbol = Symbol('ObjectReference') const objectRefIter = iterBigInt(1001n, MAX_UINT512) +/** @internal */ export const getObjectReference = (obj: DeliberateAny): bigint => { const tryGetReference = (obj: DeliberateAny): bigint | undefined => { const s = Object.getOwnPropertySymbols(obj).find((s) => s.toString() === ObjectReferenceSymbol.toString()) @@ -127,6 +187,7 @@ export const getObjectReference = (obj: DeliberateAny): bigint => { return ref } +/** @internal */ export const combineIntoMaxBytePages = (pages: bytes[]): bytes[] => { const combined = pages.reduce((acc, x) => acc.concat(x), asBytesCls('')) const totalPages = (asNumber(combined.length) + MAX_BYTES_SIZE - 1) / MAX_BYTES_SIZE @@ -140,6 +201,7 @@ export const combineIntoMaxBytePages = (pages: bytes[]): bytes[] => { return result } +/** @internal */ export const conactUint8Arrays = (...values: Uint8Array[]): Uint8Array => { const result = new Uint8Array(values.reduce((acc, value) => acc + value.length, 0)) let index = 0 @@ -150,6 +212,7 @@ export const conactUint8Arrays = (...values: Uint8Array[]): Uint8Array => { return result } +/** @internal */ export const uint8ArrayToNumber = (value: Uint8Array): number => { return value.reduce((acc, x) => acc * 256 + x, 0) } @@ -169,6 +232,7 @@ export const uint8ArrayToNumber = (value: Uint8Array): number => { * assert(false, "This will throw"); // throws AssertError: This will throw * ``` */ +/** @internal */ export function assert(condition: unknown, message?: string): asserts condition { if (!condition) { throw new AssertError(message ?? 'Assertion failed') @@ -190,6 +254,7 @@ export function assert(condition: unknown, message?: string): asserts condition * } * ``` */ +/** @internal */ export function err(message?: string): never { throw new AvmError(message ?? 'err opcode executed') } diff --git a/src/value-generators/arc4.ts b/src/value-generators/arc4.ts index 119032c..4c1fef4 100644 --- a/src/value-generators/arc4.ts +++ b/src/value-generators/arc4.ts @@ -20,8 +20,8 @@ export class Arc4ValueGenerator { /** * Generate a random Uint8 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2 ** 8 - 1. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2 ** 8 - 1. * @returns: A random Uint8 value. * */ uint8(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT8): arc4.Uint8 { @@ -30,8 +30,8 @@ export class Arc4ValueGenerator { /** * Generate a random Uint16 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2 ** 16 - 1. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2 ** 16 - 1. * @returns: A random Uint16 value. * */ uint16(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT16): arc4.Uint16 { @@ -40,8 +40,8 @@ export class Arc4ValueGenerator { /** * Generate a random Uint32 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2 ** 32 - 1. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2 ** 32 - 1. * @returns: A random Uint32 value. * */ uint32(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT32): arc4.Uint32 { @@ -50,8 +50,8 @@ export class Arc4ValueGenerator { /** * Generate a random Uint64 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 64n - 1n. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2n ** 64n - 1n. * @returns: A random Uint64 value. * */ uint64(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT64): arc4.Uint64 { @@ -60,9 +60,9 @@ export class Arc4ValueGenerator { /** * Generate a random Uint128 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 128n - 1n. - * @returns: A random Uint128 value. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2n ** 128n - 1n. + * @returns A random Uint128 value. * */ uint128(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT128): arc4.Uint128 { return new Uint({ name: 'Uint', genericArgs: [{ name: '128' }] }, getRandomBigInt(minValue, maxValue)) as arc4.Uint128 @@ -70,9 +70,9 @@ export class Arc4ValueGenerator { /** * Generate a random Uint256 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 256n - 1n. - * @returns: A random Uint256 value. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2n ** 256n - 1n. + * @returns A random Uint256 value. * */ uint256(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT256): arc4.Uint256 { return new Uint({ name: 'Uint', genericArgs: [{ name: '256' }] }, getRandomBigInt(minValue, maxValue)) as arc4.Uint256 @@ -80,9 +80,9 @@ export class Arc4ValueGenerator { /** * Generate a random Uint512 within the specified range. - * @param minValue: Minimum value (inclusive). Defaults to 0. - * @param maxValue: Maximum value (inclusive). Defaults to 2n ** 512n - 1n. - * @returns: A random Uint512 value. + * @param minValue Minimum value (inclusive). Defaults to 0. + * @param maxValue Maximum value (inclusive). Defaults to 2n ** 512n - 1n. + * @returns A random Uint512 value. * */ uint512(minValue: number | bigint = 0, maxValue: number | bigint = MAX_UINT512): arc4.Uint<512> { return new Uint({ name: 'Uint', genericArgs: [{ name: '512' }] }, getRandomBigInt(minValue, maxValue)) as arc4.Uint<512> @@ -90,9 +90,9 @@ export class Arc4ValueGenerator { /** * Generate a random dynamic bytes of size `n` bits. - * @param n: The number of bits for the dynamic bytes. Must be a multiple of 8, otherwise + * @param n The number of bits for the dynamic bytes. Must be a multiple of 8, otherwise * the last byte will be truncated. - * @returns: A new, random dynamic bytes of size `n` bits. + * @returns A new, random dynamic bytes of size `n` bits. * */ dynamicBytes(n: number): arc4.DynamicBytes { return new DynamicBytes( @@ -103,8 +103,8 @@ export class Arc4ValueGenerator { /** * Generate a random dynamic string of size `n` bits. - * @param n: The number of bits for the string. - * @returns: A new, random string of size `n` bits. + * @param n The number of bits for the string. + * @returns A new, random string of size `n` bits. * */ str(n: number): arc4.Str { // Calculate the number of characters needed (rounding up) diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index 526561c..1dcd4ec 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -3,39 +3,41 @@ import type { Application as ApplicationType, Asset as AssetType, biguint, + BigUintCompat, bytes, uint64, + Uint64Compat, } from '@algorandfoundation/algorand-typescript' import { randomBytes } from 'crypto' import { MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT64 } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { InternalError } from '../errors' -import { BigUint, Bytes, Uint64, type StubBigUintCompat, type StubUint64Compat } from '../impl/primitives' +import { BigUint, Bytes, Uint64 } from '../impl/primitives' import type { AssetData } from '../impl/reference' import { Account, AccountData, ApplicationCls, ApplicationData, AssetCls, getDefaultAssetData } from '../impl/reference' -import { asBigInt, asBigUintCls, asUint64Cls, getRandomBigInt, getRandomBytes } from '../util' +import { asBigInt, asBigUintCls, asUint64, asUint64Cls, getRandomBigInt, getRandomBytes } from '../util' type AccountContextData = Partial & { address?: bytes incentiveEligible?: boolean lastProposed?: uint64 lastHeartbeat?: uint64 - optedAssetBalances?: Map + optedAssetBalances?: Map optedApplications?: ApplicationType[] } -type AssetContextData = Partial & { assetId?: StubUint64Compat } +type AssetContextData = Partial & { assetId?: Uint64Compat } -type ApplicationContextData = Partial & { applicationId?: StubUint64Compat } +type ApplicationContextData = Partial & { applicationId?: Uint64Compat } export class AvmValueGenerator { /** * Generates a random uint64 value within the specified range. - * @param {StubUint64Compat} [minValue=0n] - The minimum value (inclusive). - * @param {StubUint64Compat} [maxValue=MAX_UINT64] - The maximum value (inclusive). + * @param {Uint64Compat} [minValue=0n] - The minimum value (inclusive). + * @param {Uint64Compat} [maxValue=MAX_UINT64] - The maximum value (inclusive). * @returns {uint64} - A random uint64 value. */ - uint64(minValue: StubUint64Compat = 0n, maxValue: StubUint64Compat = MAX_UINT64): uint64 { + uint64(minValue: Uint64Compat = 0n, maxValue: Uint64Compat = MAX_UINT64): uint64 { const min = asBigInt(minValue) const max = asBigInt(maxValue) if (max > MAX_UINT64) { @@ -52,10 +54,10 @@ export class AvmValueGenerator { /** * Generates a random biguint value within the specified range. - * @param {StubBigUintCompat} [minValue=0n] - The minimum value (inclusive). + * @param {BigUintCompat} [minValue=0n] - The minimum value (inclusive). * @returns {biguint} - A random biguint value. */ - biguint(minValue: StubBigUintCompat = 0n): biguint { + biguint(minValue: BigUintCompat = 0n): biguint { const min = asBigUintCls(minValue).asBigInt() if (min < 0n) { throw new InternalError('minValue must be greater than or equal to 0') @@ -132,17 +134,17 @@ export class AvmValueGenerator { */ asset(input?: AssetContextData): AssetType { const id = input?.assetId - if (id && lazyContext.ledger.assetDataMap.has(id)) { + if (id && lazyContext.ledger.assetDataMap.has(asUint64(id))) { throw new InternalError('Asset with such ID already exists in testing context!') } - const assetId = asUint64Cls(id ?? lazyContext.ledger.assetIdIter.next().value) + const assetId = asUint64Cls(id ?? lazyContext.ledger.assetIdIter.next().value).asAlgoTs() const defaultAssetData = getDefaultAssetData() const { assetId: _, ...assetData } = input ?? {} lazyContext.ledger.assetDataMap.set(assetId, { ...defaultAssetData, ...assetData, }) - return new AssetCls(assetId.asAlgoTs()) + return new AssetCls(assetId) } /** @@ -155,7 +157,7 @@ export class AvmValueGenerator { if (id && lazyContext.ledger.applicationDataMap.has(id)) { throw new InternalError('Application with such ID already exists in testing context!') } - const applicationId = asUint64Cls(id ?? lazyContext.ledger.appIdIter.next().value) + const applicationId = asUint64Cls(id ?? lazyContext.ledger.appIdIter.next().value).asAlgoTs() const data = new ApplicationData() const { applicationId: _, ...applicationData } = input ?? {} data.application = { @@ -163,6 +165,6 @@ export class AvmValueGenerator { ...applicationData, } lazyContext.ledger.applicationDataMap.set(applicationId, data) - return new ApplicationCls(applicationId.asAlgoTs()) + return new ApplicationCls(applicationId) } } diff --git a/src/value-generators/index.ts b/src/value-generators/index.ts index f077945..cd7ca27 100644 --- a/src/value-generators/index.ts +++ b/src/value-generators/index.ts @@ -6,6 +6,7 @@ export class ValueGenerator extends AvmValueGenerator { txn: TxnValueGenerator arc4: Arc4ValueGenerator + /** @internal */ constructor() { super() this.txn = new TxnValueGenerator() diff --git a/src/value-generators/txn.ts b/src/value-generators/txn.ts index 9864632..1be276a 100644 --- a/src/value-generators/txn.ts +++ b/src/value-generators/txn.ts @@ -1,4 +1,4 @@ -import type { Application as ApplicationType, gtxn } from '@algorandfoundation/algorand-typescript' +import type { Application as ApplicationType, BaseContract as BaseContractType, gtxn } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { InternalError } from '../errors' import { BaseContract } from '../impl/base-contract' @@ -20,7 +20,7 @@ export class TxnValueGenerator { * @returns {ApplicationCallTransaction} - A random application call transaction. */ applicationCall( - fields?: Partial & { appId: ApplicationType | BaseContract }>, + fields?: Partial & { appId: ApplicationType | BaseContractType }>, ): ApplicationCallTransaction { const params = fields ?? {} let appId = diff --git a/typedoc.json b/typedoc.json index 103799e..c1b5e8a 100644 --- a/typedoc.json +++ b/typedoc.json @@ -2,18 +2,26 @@ "$schema": "https://typedoc.org/schema.json", "entryPoints": [ "./src/index.ts", - "./src/value-generators/*.ts", - "./src/subcontexts/*.ts", "./src/test-transformer/jest-transformer.ts", - "./src/test-transformer/vitest-transformer.ts" + "./src/test-transformer/vitest-transformer.ts", + "./src/value-generators/index.ts" ], - "exclude": ["types/*.spec.ts"], - "entryPointStrategy": "expand", - "out": "docs/code", - "plugin": ["typedoc-plugin-markdown"], - "theme": "default", + "excludeInternal": true, + "excludeReferences": true, + "excludeExternals": true, + "excludePrivate": true, + "excludeProtected": true, + "includeHierarchySummary": false, + "outputs": [ + { + "name": "html", + "path": "docs/_html" + } + ], + "name": "Algorand TypeScript Testing", + "projectDocuments": ["docs/testing-guide.md", "docs/algots.md", "docs/api.md", "docs/coverage.md", "docs/examples.md", "docs/faq.md"], + "plugin": ["typedoc-plugin-missing-exports", "typedoc-plugin-markdown"], "cleanOutputDir": true, - "githubPages": false, - "readme": "none", + "readme": "docs/readme.md", "gitRevision": "main" }