From ad7dc8ebdd600b1d6731b923fd75c734ff460f37 Mon Sep 17 00:00:00 2001 From: Joe Polny <50534337+joe-p@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:01:03 -0400 Subject: [PATCH] feat: AlgorandClient and related classes (#234) * feat: client and composer * add composer and client to index.ts * fix flatFee check * fix typos Co-authored-by: Tristan Menzel * implement isAbiValue Co-authored-by: Tristan Menzel * txnMethodMap * return txnWithSigners instead of mutating co-authored-by: Tristan Menzel * improve methodCalls efficiency co-authored-by: Tristan Menzel * refactor: Use switch blocks over if/else chains * send and transaction * rm debug from test * implement max fee in composer * start adding comments * assetOptIn * add more comments * flatFee -> staticFee * Uint8Array | string * bigint and AlgoAmount * Tweaks to AlgorandClient: (#248) * Tweaks to AlgorandClient: * Rename AlgoKitClient to AlgorandClient and added static construction methods * Added fluent with* methods to AlgorandClient to allow for fluent configuration * Extracted client related stuff to ClientManager and account stuff to AccountManager and added extra functionality to both * Add transaction and confirmation to the result of sending a single transaction for better ergonomics * Added ability to specify suggested params and create a copy of suggested params when providing it * Moved classes to types directory * Added getAccountInformation to make tests terser (this method should have been added ages ago) * Incorporated client into testing fixture * Changed all possible bigint | numbers' to number (where it's impractical for them to hit 2^53) * Incorporated TransactionSignerAccount with TransactionSigner to allow for terser code * Rename ID to Id for consistency with rest of algokit utils * use bigint where applicable --------- Co-authored-by: Joe Polny * fix rollup issues * to -> receiver * getAccountAssetInformation * change with... methods to set... * persistent algorandClient * defaultValidityWindow configuration * fix AlgorandClient export * closeRemainderTo * onlineKeyReg * update asset param comments * AlgokitComposerParams * AccountManager TSDoc * generate docs * refactor: Added final polish for beta release of AlgorandClient and AlgoKitComposer test: Fixing indexer intermittent test timeouts with 20s waits for tests that wait for indexer * rm aliases * atc property and status check on build * common build step in buildMethodCall * export AlgorandClient * fix typo * use beta tag * revert test changes made in 15ba017 * fix circular import --------- Co-authored-by: Tristan Menzel Co-authored-by: Tristan Menzel Co-authored-by: Rob Moore (MakerX) --- docs/code/README.md | 5 + .../classes/types_account.MultisigAccount.md | 20 +- .../classes/types_account.SigningAccount.md | 16 +- .../types_account_manager.AccountManager.md | 565 ++++++++++++ .../types_algorand_client.AlgorandClient.md | 598 +++++++++++++ .../types_client_manager.ClientManager.md | 281 ++++++ docs/code/classes/types_composer.default.md | 765 ++++++++++++++++ .../interfaces/types_account.AccountConfig.md | 8 +- .../types_account.TransactionSignerAccount.md | 4 +- .../types_client_manager.AlgoSdkClients.md | 51 ++ .../types_client_manager.TypedAppClient.md | 40 + .../types_composer.ExecuteParams.md | 38 + .../types_network_client.AlgoConfig.md | 4 +- .../types_testing.AlgoKitLogCaptureFixture.md | 6 +- .../types_testing.AlgorandFixture.md | 21 +- .../types_testing.AlgorandFixtureConfig.md | 10 +- ...s_testing.AlgorandTestAutomationContext.md | 24 +- .../types_testing.GetTestAccountParams.md | 6 +- .../types_testing.LogSnapshotConfig.md | 6 +- ...saction.AtomicTransactionComposerToSend.md | 4 +- ..._transaction.ConfirmedTransactionResult.md | 2 +- ...transaction.ConfirmedTransactionResults.md | 4 +- ...on.SendAtomicTransactionComposerResults.md | 6 +- ...ypes_transaction.TransactionGroupToSend.md | 6 +- .../types_transaction.TransactionToSign.md | 4 +- docs/code/modules/index.md | 103 ++- docs/code/modules/testing.md | 4 +- docs/code/modules/types_account.md | 40 +- docs/code/modules/types_account_manager.md | 9 + docs/code/modules/types_algorand_client.md | 35 + .../modules/types_algorand_client_spec.md | 3 + docs/code/modules/types_client_manager.md | 69 ++ docs/code/modules/types_composer.md | 197 +++++ docs/code/modules/types_transaction.md | 2 +- src/account/account.ts | 73 +- src/index.ts | 1 + src/indexer-lookup.spec.ts | 75 +- src/testing/fixtures/algorand-fixture.ts | 26 +- src/types/account-manager.ts | 290 ++++++ src/types/account.ts | 18 + src/types/algorand-client.spec.ts | 199 +++++ src/types/algorand-client.ts | 343 ++++++++ src/types/client-manager.ts | 162 ++++ src/types/composer.ts | 771 ++++++++++++++++ src/types/network-client.ts | 4 +- src/types/testing.ts | 11 +- src/types/transaction.ts | 4 + .../client/TestContractClient.ts | 826 ++++++++++++++++++ 48 files changed, 5598 insertions(+), 161 deletions(-) create mode 100644 docs/code/classes/types_account_manager.AccountManager.md create mode 100644 docs/code/classes/types_algorand_client.AlgorandClient.md create mode 100644 docs/code/classes/types_client_manager.ClientManager.md create mode 100644 docs/code/classes/types_composer.default.md create mode 100644 docs/code/interfaces/types_client_manager.AlgoSdkClients.md create mode 100644 docs/code/interfaces/types_client_manager.TypedAppClient.md create mode 100644 docs/code/interfaces/types_composer.ExecuteParams.md create mode 100644 docs/code/modules/types_account_manager.md create mode 100644 docs/code/modules/types_algorand_client.md create mode 100644 docs/code/modules/types_algorand_client_spec.md create mode 100644 docs/code/modules/types_client_manager.md create mode 100644 docs/code/modules/types_composer.md create mode 100644 src/types/account-manager.ts create mode 100644 src/types/algorand-client.spec.ts create mode 100644 src/types/algorand-client.ts create mode 100644 src/types/client-manager.ts create mode 100644 src/types/composer.ts create mode 100644 tests/example-contracts/client/TestContractClient.ts diff --git a/docs/code/README.md b/docs/code/README.md index df056d65..61d7835e 100644 --- a/docs/code/README.md +++ b/docs/code/README.md @@ -9,7 +9,10 @@ - [index](modules/index.md) - [testing](modules/testing.md) - [types/account](modules/types_account.md) +- [types/account-manager](modules/types_account_manager.md) - [types/algo-http-client-with-retry](modules/types_algo_http_client_with_retry.md) +- [types/algorand-client](modules/types_algorand_client.md) +- [types/algorand-client.spec](modules/types_algorand_client_spec.md) - [types/amount](modules/types_amount.md) - [types/amount.spec](modules/types_amount_spec.md) - [types/app](modules/types_app.md) @@ -17,6 +20,8 @@ - [types/app-client.spec](modules/types_app_client_spec.md) - [types/app-spec](modules/types_app_spec.md) - [types/asset](modules/types_asset.md) +- [types/client-manager](modules/types_client_manager.md) +- [types/composer](modules/types_composer.md) - [types/config](modules/types_config.md) - [types/debugging](modules/types_debugging.md) - [types/dispenser-client](modules/types_dispenser_client.md) diff --git a/docs/code/classes/types_account.MultisigAccount.md b/docs/code/classes/types_account.MultisigAccount.md index 87f42411..4fb42093 100644 --- a/docs/code/classes/types_account.MultisigAccount.md +++ b/docs/code/classes/types_account.MultisigAccount.md @@ -49,7 +49,7 @@ Account wrapper that supports partial or full multisig signing. #### Defined in -[src/types/account.ts:38](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L38) +[src/types/account.ts:39](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L39) ## Properties @@ -59,7 +59,7 @@ Account wrapper that supports partial or full multisig signing. #### Defined in -[src/types/account.ts:16](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L16) +[src/types/account.ts:17](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L17) ___ @@ -69,7 +69,7 @@ ___ #### Defined in -[src/types/account.ts:14](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L14) +[src/types/account.ts:15](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L15) ___ @@ -79,7 +79,7 @@ ___ #### Defined in -[src/types/account.ts:17](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L17) +[src/types/account.ts:18](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L18) ___ @@ -89,7 +89,7 @@ ___ #### Defined in -[src/types/account.ts:15](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L15) +[src/types/account.ts:16](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L16) ## Accessors @@ -105,7 +105,7 @@ The address of the multisig account #### Defined in -[src/types/account.ts:30](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L30) +[src/types/account.ts:31](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L31) ___ @@ -121,7 +121,7 @@ The parameters for the multisig account #### Defined in -[src/types/account.ts:20](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L20) +[src/types/account.ts:21](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L21) ___ @@ -135,7 +135,7 @@ ___ #### Defined in -[src/types/account.ts:34](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L34) +[src/types/account.ts:35](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L35) ___ @@ -151,7 +151,7 @@ readonly (`default` \| [`SigningAccount`](types_account.SigningAccount.md))[] #### Defined in -[src/types/account.ts:25](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L25) +[src/types/account.ts:26](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L26) ## Methods @@ -175,4 +175,4 @@ The transaction signed by the present signers #### Defined in -[src/types/account.ts:53](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L53) +[src/types/account.ts:54](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L54) diff --git a/docs/code/classes/types_account.SigningAccount.md b/docs/code/classes/types_account.SigningAccount.md index 5b49f1e4..1304b0d7 100644 --- a/docs/code/classes/types_account.SigningAccount.md +++ b/docs/code/classes/types_account.SigningAccount.md @@ -48,7 +48,7 @@ Account wrapper that supports a rekeyed account #### Defined in -[src/types/account.ts:104](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L104) +[src/types/account.ts:105](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L105) ## Properties @@ -58,7 +58,7 @@ Account wrapper that supports a rekeyed account #### Defined in -[src/types/account.ts:69](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L69) +[src/types/account.ts:70](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L70) ___ @@ -68,7 +68,7 @@ ___ #### Defined in -[src/types/account.ts:71](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L71) +[src/types/account.ts:72](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L72) ___ @@ -78,7 +78,7 @@ ___ #### Defined in -[src/types/account.ts:70](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L70) +[src/types/account.ts:71](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L71) ## Accessors @@ -98,7 +98,7 @@ Account.addr #### Defined in -[src/types/account.ts:76](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L76) +[src/types/account.ts:77](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L77) ___ @@ -114,7 +114,7 @@ Algorand account of the sender address and signer private key #### Defined in -[src/types/account.ts:97](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L97) +[src/types/account.ts:98](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L98) ___ @@ -130,7 +130,7 @@ Transaction signer for the underlying signing account #### Defined in -[src/types/account.ts:90](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L90) +[src/types/account.ts:91](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L91) ___ @@ -150,4 +150,4 @@ Account.sk #### Defined in -[src/types/account.ts:83](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L83) +[src/types/account.ts:84](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L84) diff --git a/docs/code/classes/types_account_manager.AccountManager.md b/docs/code/classes/types_account_manager.AccountManager.md new file mode 100644 index 00000000..ac2800fe --- /dev/null +++ b/docs/code/classes/types_account_manager.AccountManager.md @@ -0,0 +1,565 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/account-manager](../modules/types_account_manager.md) / AccountManager + +# Class: AccountManager + +[types/account-manager](../modules/types_account_manager.md).AccountManager + +Creates and keeps track of signing accounts that can sign transactions for a sending address. + +## Table of contents + +### Constructors + +- [constructor](types_account_manager.AccountManager.md#constructor) + +### Properties + +- [\_accounts](types_account_manager.AccountManager.md#_accounts) +- [\_clientManager](types_account_manager.AccountManager.md#_clientmanager) +- [\_defaultSigner](types_account_manager.AccountManager.md#_defaultsigner) + +### Methods + +- [dispenser](types_account_manager.AccountManager.md#dispenser) +- [fromEnvironment](types_account_manager.AccountManager.md#fromenvironment) +- [fromKmd](types_account_manager.AccountManager.md#fromkmd) +- [fromMnemonic](types_account_manager.AccountManager.md#frommnemonic) +- [getAccount](types_account_manager.AccountManager.md#getaccount) +- [getAssetInformation](types_account_manager.AccountManager.md#getassetinformation) +- [getInformation](types_account_manager.AccountManager.md#getinformation) +- [getSigner](types_account_manager.AccountManager.md#getsigner) +- [localNetDispenser](types_account_manager.AccountManager.md#localnetdispenser) +- [logicsig](types_account_manager.AccountManager.md#logicsig) +- [multisig](types_account_manager.AccountManager.md#multisig) +- [random](types_account_manager.AccountManager.md#random) +- [setDefaultSigner](types_account_manager.AccountManager.md#setdefaultsigner) +- [setSigner](types_account_manager.AccountManager.md#setsigner) +- [setSignerFromAccount](types_account_manager.AccountManager.md#setsignerfromaccount) +- [signerAccount](types_account_manager.AccountManager.md#signeraccount) + +## Constructors + +### constructor + +• **new AccountManager**(`clientManager`): [`AccountManager`](types_account_manager.AccountManager.md) + +Create a new account manager. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `clientManager` | [`ClientManager`](types_client_manager.ClientManager.md) | The ClientManager client to use for algod and kmd clients | + +#### Returns + +[`AccountManager`](types_account_manager.AccountManager.md) + +#### Defined in + +[src/types/account-manager.ts:31](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L31) + +## Properties + +### \_accounts + +• `Private` **\_accounts**: `Object` = `{}` + +#### Index signature + +▪ [address: `string`]: [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) + +#### Defined in + +[src/types/account-manager.ts:24](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L24) + +___ + +### \_clientManager + +• `Private` **\_clientManager**: [`ClientManager`](types_client_manager.ClientManager.md) + +#### Defined in + +[src/types/account-manager.ts:23](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L23) + +___ + +### \_defaultSigner + +• `Private` `Optional` **\_defaultSigner**: `TransactionSigner` + +#### Defined in + +[src/types/account-manager.ts:25](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L25) + +## Methods + +### dispenser + +▸ **dispenser**(): `Promise`\<`void`\> + +Returns an account (with private key loaded) that can act as a dispenser. + +#### Returns + +`Promise`\<`void`\> + +The account + +**`Example`** + +```typescript +const account = await account.dispenser() +``` +If running on LocalNet then it will return the default dispenser account automatically, + otherwise it will load the account mnemonic stored in process.env.DISPENSER_MNEMONIC. + +#### Defined in + +[src/types/account-manager.ts:274](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L274) + +___ + +### fromEnvironment + +▸ **fromEnvironment**(`name`, `fundWith?`): `Promise`\<`void`\> + +Tracks and returns an Algorand account with private key loaded by convention from environment variables based on the given name identifier. + +Note: This function expects to run in a Node.js environment. + +## Convention: +* **Non-LocalNet:** will load process.env['{NAME}_MNEMONIC'] as a mnemonic secret; **Note: Be careful how the mnemonic is handled**, + never commit it into source control and ideally load it via a secret storage service rather than the file system. + If process.env['{NAME}_SENDER'] is defined then it will use that for the sender address (i.e. to support rekeyed accounts) +* **LocalNet:** will load the account from a KMD wallet called {NAME} and if that wallet doesn't exist it will create it and fund the account for you + +This allows you to write code that will work seamlessly in production and local development (LocalNet) without manual config locally (including when you reset the LocalNet). + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | The name identifier of the account | +| `fundWith?` | [`AlgoAmount`](types_amount.AlgoAmount.md) | The optional amount to fund the account with when it gets created (when targeting LocalNet), if not specified then 1000 Algos will be funded from the dispenser account | + +#### Returns + +`Promise`\<`void`\> + +The account + +**`Example`** + +If you have a mnemonic secret loaded into `process.env.MY_ACCOUNT_MNEMONIC` then you can call the following to get that private key loaded into an account object: +```typescript +const account = await account.fromEnvironment('MY_ACCOUNT', algod) +``` + +If that code runs against LocalNet then a wallet called `MY_ACCOUNT` will automatically be created with an account that is automatically funded with 1000 (default) ALGOs from the default LocalNet dispenser. +If not running against LocalNet then it will use proces.env.MY_ACCOUNT_MNEMONIC as the private key and (if present) process.env.MY_ACCOUNT_SENDER as the sender address. + +#### Defined in + +[src/types/account-manager.ts:189](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L189) + +___ + +### fromKmd + +▸ **fromKmd**(`name`, `predicate?`, `sender?`): `Promise`\<[`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: `default` \| [`SigningAccount`](types_account.SigningAccount.md) }\> + +Tracks and returns an Algorand account with private key loaded from the given KMD wallet (identified by name). + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | The name of the wallet to retrieve an account from | +| `predicate?` | (`account`: `Record`\<`string`, `any`\>) => `boolean` | An optional filter to use to find the account (otherwise it will return a random account from the wallet) | +| `sender?` | `string` | The optional sender address to use this signer for (aka a rekeyed account) | + +#### Returns + +`Promise`\<[`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: `default` \| [`SigningAccount`](types_account.SigningAccount.md) }\> + +The account + +**`Example`** + +```typescript +const defaultDispenserAccount = await account.fromKmd('unencrypted-default-wallet', + a => a.status !== 'Offline' && a.amount > 1_000_000_000 +) +``` + +#### Defined in + +[src/types/account-manager.ts:208](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L208) + +___ + +### fromMnemonic + +▸ **fromMnemonic**(`mnemonicSecret`, `sender?`): [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: `default` \| [`SigningAccount`](types_account.SigningAccount.md) } + +Tracks and returns an Algorand account with secret key loaded (i.e. that can sign transactions) by taking the mnemonic secret. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `mnemonicSecret` | `string` | The mnemonic secret representing the private key of an account; **Note: Be careful how the mnemonic is handled**, never commit it into source control and ideally load it from the environment (ideally via a secret storage service) rather than the file system. | +| `sender?` | `string` | The optional sender address to use this signer for (aka a rekeyed account) | + +#### Returns + +[`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: `default` \| [`SigningAccount`](types_account.SigningAccount.md) } + +The account + +**`Example`** + +```typescript +const account = await account.fromMnemonic("mnemonic secret ...") +const rekeyedAccount = await account.fromMnemonic("mnemonic secret ...", "SENDERADDRESS...") +``` + +#### Defined in + +[src/types/account-manager.ts:157](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L157) + +___ + +### getAccount + +▸ **getAccount**(`sender`): [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) + +Returns the `TransactionSignerAccount` for the given sender address. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` | The sender address | + +#### Returns + +[`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) + +The `TransactionSignerAccount` or throws an error if not found + +#### Defined in + +[src/types/account-manager.ts:102](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L102) + +___ + +### getAssetInformation + +▸ **getAssetInformation**(`sender`, `assetId`): `Promise`\<[`AccountAssetInformation`](../modules/types_account.md#accountassetinformation)\> + +Returns the given sender account's asset holding for a given asset. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` \| [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) | The address of the sender/account to look up | +| `assetId` | `number` \| `bigint` | The ID of the asset to return a holding for | + +#### Returns + +`Promise`\<[`AccountAssetInformation`](../modules/types_account.md#accountassetinformation)\> + +The account asset holding information + +**`Example`** + +```typescript +const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; +const assetId = 123345; +const accountInfo = await accountManager.getAccountAssetInformation(address, assetId); +``` + +[Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddressassetsasset-id) + +#### Defined in + +[src/types/account-manager.ts:140](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L140) + +___ + +### getInformation + +▸ **getInformation**(`sender`): `Promise`\<[`AccountInformation`](../modules/types_account.md#accountinformation)\> + +Returns the given sender account's current status, balance and spendable amounts. + +[Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddress) + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` \| [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) | The account / address to look up | + +#### Returns + +`Promise`\<[`AccountInformation`](../modules/types_account.md#accountinformation)\> + +The account information + +**`Example`** + +```typescript +const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; +const accountInfo = await accountManager.getInformation(address); +``` + +#### Defined in + +[src/types/account-manager.ts:121](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L121) + +___ + +### getSigner + +▸ **getSigner**(`sender`): `TransactionSigner` + +Returns the `TransactionSigner` for the given sender address. + +If no signer has been registered for that address then the default signer is used if registered. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` | The sender address | + +#### Returns + +`TransactionSigner` + +The `TransactionSigner` or throws an error if not found + +#### Defined in + +[src/types/account-manager.ts:91](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L91) + +___ + +### localNetDispenser + +▸ **localNetDispenser**(): `Promise`\<`void`\> + +Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts). + +#### Returns + +`Promise`\<`void`\> + +The account + +**`Example`** + +```typescript +const account = await account.localNetDispenser() +``` + +#### Defined in + +[src/types/account-manager.ts:287](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L287) + +___ + +### logicsig + +▸ **logicsig**(`program`, `args?`): `void` + +Tracks and returns an account that represents a logic signature. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `program` | `Uint8Array` | The bytes that make up the compiled logic signature | +| `args?` | `Uint8Array`[] | The (binary) arguments to pass into the logic signature | + +#### Returns + +`void` + +A logic signature account wrapper + +**`Example`** + +```typescript +const account = await account.logicsig(program, [new Uint8Array(3, ...)]) +``` + +#### Defined in + +[src/types/account-manager.ts:246](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L246) + +___ + +### multisig + +▸ **multisig**(`multisigParams`, `signingAccounts`): [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: [`MultisigAccount`](types_account.MultisigAccount.md) } + +Tracks and returns an account that supports partial or full multisig signing. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `multisigParams` | `MultisigMetadata` | The parameters that define the multisig account | +| `signingAccounts` | (`default` \| [`SigningAccount`](types_account.SigningAccount.md))[] | The signers that are currently present | + +#### Returns + +[`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: [`MultisigAccount`](types_account.MultisigAccount.md) } + +A multisig account wrapper + +**`Example`** + +```typescript +const account = await account.multisig({version: 1, threshold: 1, addrs: ["ADDRESS1...", "ADDRESS2..."]}, + await account.fromEnvironment('ACCOUNT1')) +``` + +#### Defined in + +[src/types/account-manager.ts:231](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L231) + +___ + +### random + +▸ **random**(): `void` + +Tracks and returns a new, random Algorand account with secret key loaded. + +#### Returns + +`void` + +The account + +**`Example`** + +```typescript +const account = await account.random() +``` + +#### Defined in + +[src/types/account-manager.ts:259](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L259) + +___ + +### setDefaultSigner + +▸ **setDefaultSigner**(`signer`): [`AccountManager`](types_account_manager.AccountManager.md) + +Sets the default signer to use if no other signer is specified. + +If this isn't set an a transaction needs signing for a given sender +then an error will be thrown from `getSigner` / `getAccount`. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `signer` | `TransactionSigner` \| [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) | The signer to use, either a `TransactionSigner` or a `TransactionSignerAccount` | + +#### Returns + +[`AccountManager`](types_account_manager.AccountManager.md) + +The `AccountManager` so method calls can be chained + +#### Defined in + +[src/types/account-manager.ts:43](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L43) + +___ + +### setSigner + +▸ **setSigner**(`sender`, `signer`): [`AccountManager`](types_account_manager.AccountManager.md) + +Tracks the given account for later signing. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` | The sender address to use this signer for | +| `signer` | `TransactionSigner` | The signer to sign transactions with for the given sender | + +#### Returns + +[`AccountManager`](types_account_manager.AccountManager.md) + +The `AccountManager` instance for method chaining + +#### Defined in + +[src/types/account-manager.ts:78](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L78) + +___ + +### setSignerFromAccount + +▸ **setSignerFromAccount**(`account`): [`AccountManager`](types_account_manager.AccountManager.md) + +Tracks the given account for later signing. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `account` | [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom) | The account to register, which can be a `TransactionSignerAccount` or any `SendTransactionFrom` compatible account object | + +#### Returns + +[`AccountManager`](types_account_manager.AccountManager.md) + +The `AccountManager` instance for method chaining + +#### Defined in + +[src/types/account-manager.ts:67](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L67) + +___ + +### signerAccount + +▸ **signerAccount**\<`T`\>(`account`): [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: `T` } + +Records the given account against the address of the account for later +retrieval and returns a `TransactionSignerAccount`. + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | extends [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom) | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `account` | `T` | + +#### Returns + +[`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) & \{ `account`: `T` } + +#### Defined in + +[src/types/account-manager.ts:52](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L52) diff --git a/docs/code/classes/types_algorand_client.AlgorandClient.md b/docs/code/classes/types_algorand_client.AlgorandClient.md new file mode 100644 index 00000000..9440591b --- /dev/null +++ b/docs/code/classes/types_algorand_client.AlgorandClient.md @@ -0,0 +1,598 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/algorand-client](../modules/types_algorand_client.md) / AlgorandClient + +# Class: AlgorandClient + +[types/algorand-client](../modules/types_algorand_client.md).AlgorandClient + +A client that brokers easy access to Algorand functionality. + +Note: this class is a new Beta feature and may be subject to change. + +## Table of contents + +### Constructors + +- [constructor](types_algorand_client.AlgorandClient.md#constructor) + +### Properties + +- [\_accountManager](types_algorand_client.AlgorandClient.md#_accountmanager) +- [\_cachedSuggestedParams](types_algorand_client.AlgorandClient.md#_cachedsuggestedparams) +- [\_cachedSuggestedParamsExpiry](types_algorand_client.AlgorandClient.md#_cachedsuggestedparamsexpiry) +- [\_cachedSuggestedParamsTimeout](types_algorand_client.AlgorandClient.md#_cachedsuggestedparamstimeout) +- [\_clientManager](types_algorand_client.AlgorandClient.md#_clientmanager) +- [\_defaultValidityWindow](types_algorand_client.AlgorandClient.md#_defaultvaliditywindow) +- [send](types_algorand_client.AlgorandClient.md#send) +- [transactions](types_algorand_client.AlgorandClient.md#transactions) + +### Accessors + +- [account](types_algorand_client.AlgorandClient.md#account) +- [client](types_algorand_client.AlgorandClient.md#client) + +### Methods + +- [\_send](types_algorand_client.AlgorandClient.md#_send) +- [\_transaction](types_algorand_client.AlgorandClient.md#_transaction) +- [getSuggestedParams](types_algorand_client.AlgorandClient.md#getsuggestedparams) +- [newGroup](types_algorand_client.AlgorandClient.md#newgroup) +- [setDefaultSigner](types_algorand_client.AlgorandClient.md#setdefaultsigner) +- [setDefaultValidityWindow](types_algorand_client.AlgorandClient.md#setdefaultvaliditywindow) +- [setSigner](types_algorand_client.AlgorandClient.md#setsigner) +- [setSignerFromAccount](types_algorand_client.AlgorandClient.md#setsignerfromaccount) +- [setSuggestedParams](types_algorand_client.AlgorandClient.md#setsuggestedparams) +- [setSuggestedParamsTimeout](types_algorand_client.AlgorandClient.md#setsuggestedparamstimeout) +- [defaultLocalNet](types_algorand_client.AlgorandClient.md#defaultlocalnet) +- [fromClients](types_algorand_client.AlgorandClient.md#fromclients) +- [fromConfig](types_algorand_client.AlgorandClient.md#fromconfig) +- [fromEnvironment](types_algorand_client.AlgorandClient.md#fromenvironment) +- [mainNet](types_algorand_client.AlgorandClient.md#mainnet) +- [testNet](types_algorand_client.AlgorandClient.md#testnet) + +## Constructors + +### constructor + +• **new AlgorandClient**(`config`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `config` | [`AlgoConfig`](../interfaces/types_network_client.AlgoConfig.md) \| [`AlgoSdkClients`](../interfaces/types_client_manager.AlgoSdkClients.md) | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +#### Defined in + +[src/types/algorand-client.ts:31](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L31) + +## Properties + +### \_accountManager + +• `Private` **\_accountManager**: [`AccountManager`](types_account_manager.AccountManager.md) + +#### Defined in + +[src/types/algorand-client.ts:23](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L23) + +___ + +### \_cachedSuggestedParams + +• `Private` `Optional` **\_cachedSuggestedParams**: `SuggestedParams` + +#### Defined in + +[src/types/algorand-client.ts:25](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L25) + +___ + +### \_cachedSuggestedParamsExpiry + +• `Private` `Optional` **\_cachedSuggestedParamsExpiry**: `Date` + +#### Defined in + +[src/types/algorand-client.ts:26](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L26) + +___ + +### \_cachedSuggestedParamsTimeout + +• `Private` **\_cachedSuggestedParamsTimeout**: `number` = `3_000` + +#### Defined in + +[src/types/algorand-client.ts:27](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L27) + +___ + +### \_clientManager + +• `Private` **\_clientManager**: [`ClientManager`](types_client_manager.ClientManager.md) + +#### Defined in + +[src/types/algorand-client.ts:22](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L22) + +___ + +### \_defaultValidityWindow + +• `Private` **\_defaultValidityWindow**: `number` = `10` + +#### Defined in + +[src/types/algorand-client.ts:29](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L29) + +___ + +### send + +• **send**: `Object` + +Methods for sending a single transaction. + +#### Type declaration + +| Name | Type | Description | +| :------ | :------ | :------ | +| `appCall` | (`params`: [`AppCallParams`](../modules/types_composer.md#appcallparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `assetConfig` | (`params`: [`AssetConfigParams`](../modules/types_composer.md#assetconfigparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `assetCreate` | (`params`: [`AssetCreateParams`](../modules/types_composer.md#assetcreateparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `assetDestroy` | (`params`: [`AssetDestroyParams`](../modules/types_composer.md#assetdestroyparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `assetFreeze` | (`params`: [`AssetFreezeParams`](../modules/types_composer.md#assetfreezeparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `assetOptIn` | (`params`: [`AssetOptInParams`](../modules/types_composer.md#assetoptinparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `assetTransfer` | (`params`: [`AssetTransferParams`](../modules/types_composer.md#assettransferparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `methodCall` | (`params`: [`MethodCallParams`](../modules/types_composer.md#methodcallparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `onlineKeyRegistration` | (`params`: [`OnlineKeyRegistrationParams`](../modules/types_composer.md#onlinekeyregistrationparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | +| `payment` | (`params`: [`PaymentParams`](../modules/types_composer.md#paymentparams), `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> | - | + +#### Defined in + +[src/types/algorand-client.ts:173](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L173) + +___ + +### transactions + +• **transactions**: `Object` + +Methods for building transactions + +#### Type declaration + +| Name | Type | Description | +| :------ | :------ | :------ | +| `appCall` | (`params`: [`AppCallParams`](../modules/types_composer.md#appcallparams)) => `Promise`\<`Transaction`\> | - | +| `assetConfig` | (`params`: [`AssetConfigParams`](../modules/types_composer.md#assetconfigparams)) => `Promise`\<`Transaction`\> | - | +| `assetCreate` | (`params`: [`AssetCreateParams`](../modules/types_composer.md#assetcreateparams)) => `Promise`\<`Transaction`\> | - | +| `assetDestroy` | (`params`: [`AssetDestroyParams`](../modules/types_composer.md#assetdestroyparams)) => `Promise`\<`Transaction`\> | - | +| `assetFreeze` | (`params`: [`AssetFreezeParams`](../modules/types_composer.md#assetfreezeparams)) => `Promise`\<`Transaction`\> | - | +| `assetOptIn` | (`params`: [`AssetOptInParams`](../modules/types_composer.md#assetoptinparams)) => `Promise`\<`Transaction`\> | - | +| `assetTransfer` | (`params`: [`AssetTransferParams`](../modules/types_composer.md#assettransferparams)) => `Promise`\<`Transaction`\> | - | +| `methodCall` | (`params`: [`MethodCallParams`](../modules/types_composer.md#methodcallparams)) => `Promise`\<`Transaction`[]\> | - | +| `onlineKeyRegistration` | (`params`: [`OnlineKeyRegistrationParams`](../modules/types_composer.md#onlinekeyregistrationparams)) => `Promise`\<`Transaction`\> | - | +| `payment` | (`params`: [`PaymentParams`](../modules/types_composer.md#paymentparams)) => `Promise`\<`Transaction`\> | - | + +#### Defined in + +[src/types/algorand-client.ts:249](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L249) + +## Accessors + +### account + +• `get` **account**(): [`AccountManager`](types_account_manager.AccountManager.md) + +Get or create accounts that can sign transactions. + +#### Returns + +[`AccountManager`](types_account_manager.AccountManager.md) + +#### Defined in + +[src/types/algorand-client.ts:121](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L121) + +___ + +### client + +• `get` **client**(): [`ClientManager`](types_client_manager.ClientManager.md) + +Get clients, including algosdk clients and app clients. + +#### Returns + +[`ClientManager`](types_client_manager.ClientManager.md) + +#### Defined in + +[src/types/algorand-client.ts:116](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L116) + +## Methods + +### \_send + +▸ **_send**\<`T`\>(`c`, `log?`): (`params`: `T`, `config?`: [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md)) => `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `c` | (`c`: [`default`](types_composer.default.md)) => (`params`: `T`) => [`default`](types_composer.default.md) | +| `log?` | `Object` | +| `log.postLog?` | (`params`: `T`, `result`: [`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)) => `string` | +| `log.preLog?` | (`params`: `T`, `transaction`: `Transaction`) => `string` | + +#### Returns + +`fn` + +▸ (`params`, `config?`): `Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> + +##### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | `T` | +| `config?` | [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md) | + +##### Returns + +`Promise`\<[`SendSingleTransactionResult`](../modules/types_algorand_client.md#sendsingletransactionresult)\> + +#### Defined in + +[src/types/algorand-client.ts:135](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L135) + +___ + +### \_transaction + +▸ **_transaction**\<`T`\>(`c`): (`params`: `T`) => `Promise`\<`Transaction`\> + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `c` | (`c`: [`default`](types_composer.default.md)) => (`params`: `T`) => [`default`](types_composer.default.md) | + +#### Returns + +`fn` + +▸ (`params`): `Promise`\<`Transaction`\> + +##### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | `T` | + +##### Returns + +`Promise`\<`Transaction`\> + +#### Defined in + +[src/types/algorand-client.ts:238](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L238) + +___ + +### getSuggestedParams + +▸ **getSuggestedParams**(): `Promise`\<`SuggestedParams`\> + +Get suggested params for a transaction (either cached or from algod if the cache is stale or empty) + +#### Returns + +`Promise`\<`SuggestedParams`\> + +#### Defined in + +[src/types/algorand-client.ts:100](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L100) + +___ + +### newGroup + +▸ **newGroup**(): [`default`](types_composer.default.md) + +Start a new `AlgokitComposer` transaction group + +#### Returns + +[`default`](types_composer.default.md) + +#### Defined in + +[src/types/algorand-client.ts:126](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L126) + +___ + +### setDefaultSigner + +▸ **setDefaultSigner**(`signer`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Sets the default signer to use if no other signer is specified. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `signer` | `TransactionSigner` \| [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) | The signer to use, either a `TransactionSigner` or a `TransactionSignerAccount` | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` so method calls can be chained + +#### Defined in + +[src/types/algorand-client.ts:51](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L51) + +___ + +### setDefaultValidityWindow + +▸ **setDefaultValidityWindow**(`validityWindow`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Sets the default validity window for transactions. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `validityWindow` | `number` | The number of rounds between the first and last valid rounds | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` so method calls can be chained + +#### Defined in + +[src/types/algorand-client.ts:41](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L41) + +___ + +### setSigner + +▸ **setSigner**(`sender`, `signer`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Tracks the given account for later signing. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` | The sender address to use this signer for | +| `signer` | `TransactionSigner` | The signer to sign transactions with for the given sender | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` so method calls can be chained + +#### Defined in + +[src/types/algorand-client.ts:72](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L72) + +___ + +### setSignerFromAccount + +▸ **setSignerFromAccount**(`account`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Tracks the given account for later signing. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `account` | [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom) | The account to register | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` so method calls can be chained + +#### Defined in + +[src/types/algorand-client.ts:61](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L61) + +___ + +### setSuggestedParams + +▸ **setSuggestedParams**(`suggestedParams`, `until?`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Sets a cache value to use for suggested params. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `suggestedParams` | `SuggestedParams` | The suggested params to use | +| `until?` | `Date` | A date until which to cache, or if not specified then the timeout is used | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` so method calls can be chained + +#### Defined in + +[src/types/algorand-client.ts:83](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L83) + +___ + +### setSuggestedParamsTimeout + +▸ **setSuggestedParamsTimeout**(`timeout`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Sets the timeout for caching suggested params. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `timeout` | `number` | The timeout in milliseconds | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` so method calls can be chained + +#### Defined in + +[src/types/algorand-client.ts:94](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L94) + +___ + +### defaultLocalNet + +▸ **defaultLocalNet**(): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Returns an `AlgorandClient` pointing at default LocalNet ports and API token. + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` + +#### Defined in + +[src/types/algorand-client.ts:280](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L280) + +___ + +### fromClients + +▸ **fromClients**(`clients`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Returns an `AlgorandClient` pointing to the given client(s). + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `clients` | [`AlgoSdkClients`](../interfaces/types_client_manager.AlgoSdkClients.md) | The clients to use | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` + +#### Defined in + +[src/types/algorand-client.ts:317](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L317) + +___ + +### fromConfig + +▸ **fromConfig**(`config`): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Returns an `AlgorandClient` from the given config. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `config` | [`AlgoConfig`](../interfaces/types_network_client.AlgoConfig.md) | The config to use | + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` + +#### Defined in + +[src/types/algorand-client.ts:338](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L338) + +___ + +### fromEnvironment + +▸ **fromEnvironment**(): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Returns an `AlgorandClient` loading the configuration from environment variables. + +Retrieve configurations from environment variables when defined or get defaults. + +Expects to be called from a Node.js environment. + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` + +#### Defined in + +[src/types/algorand-client.ts:329](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L329) + +___ + +### mainNet + +▸ **mainNet**(): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Returns an `AlgorandClient` pointing at MainNet using AlgoNode. + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` + +#### Defined in + +[src/types/algorand-client.ts:304](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L304) + +___ + +### testNet + +▸ **testNet**(): [`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +Returns an `AlgorandClient` pointing at TestNet using AlgoNode. + +#### Returns + +[`AlgorandClient`](types_algorand_client.AlgorandClient.md) + +The `AlgorandClient` + +#### Defined in + +[src/types/algorand-client.ts:292](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L292) diff --git a/docs/code/classes/types_client_manager.ClientManager.md b/docs/code/classes/types_client_manager.ClientManager.md new file mode 100644 index 00000000..d16b2f3a --- /dev/null +++ b/docs/code/classes/types_client_manager.ClientManager.md @@ -0,0 +1,281 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/client-manager](../modules/types_client_manager.md) / ClientManager + +# Class: ClientManager + +[types/client-manager](../modules/types_client_manager.md).ClientManager + +Exposes access to various API clients. + +## Table of contents + +### Constructors + +- [constructor](types_client_manager.ClientManager.md#constructor) + +### Properties + +- [\_algod](types_client_manager.ClientManager.md#_algod) +- [\_indexer](types_client_manager.ClientManager.md#_indexer) +- [\_kmd](types_client_manager.ClientManager.md#_kmd) + +### Accessors + +- [algod](types_client_manager.ClientManager.md#algod) +- [indexer](types_client_manager.ClientManager.md#indexer) +- [kmd](types_client_manager.ClientManager.md#kmd) + +### Methods + +- [getAppClientByCreatorAndName](types_client_manager.ClientManager.md#getappclientbycreatorandname) +- [getAppClientById](types_client_manager.ClientManager.md#getappclientbyid) +- [getTestNetDispenser](types_client_manager.ClientManager.md#gettestnetdispenser) +- [getTypedAppClientByCreatorAndName](types_client_manager.ClientManager.md#gettypedappclientbycreatorandname) +- [getTypedAppClientById](types_client_manager.ClientManager.md#gettypedappclientbyid) + +## Constructors + +### constructor + +• **new ClientManager**(`clientsOrConfig`): [`ClientManager`](types_client_manager.ClientManager.md) + +algosdk clients or config for interacting with the official Algorand APIs. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `clientsOrConfig` | [`AlgoConfig`](../interfaces/types_network_client.AlgoConfig.md) \| [`AlgoSdkClients`](../interfaces/types_client_manager.AlgoSdkClients.md) | The clients or config to use | + +#### Returns + +[`ClientManager`](types_client_manager.ClientManager.md) + +#### Defined in + +[src/types/client-manager.ts:36](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L36) + +## Properties + +### \_algod + +• `Private` **\_algod**: `default` + +#### Defined in + +[src/types/client-manager.ts:28](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L28) + +___ + +### \_indexer + +• `Private` `Optional` **\_indexer**: `default` + +#### Defined in + +[src/types/client-manager.ts:29](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L29) + +___ + +### \_kmd + +• `Private` `Optional` **\_kmd**: `default` + +#### Defined in + +[src/types/client-manager.ts:30](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L30) + +## Accessors + +### algod + +• `get` **algod**(): `default` + +Returns an algosdk Algod API client. + +#### Returns + +`default` + +#### Defined in + +[src/types/client-manager.ts:51](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L51) + +___ + +### indexer + +• `get` **indexer**(): `default` + +Returns an algosdk Indexer API client or throws an error if it's not been provided. + +#### Returns + +`default` + +#### Defined in + +[src/types/client-manager.ts:56](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L56) + +___ + +### kmd + +• `get` **kmd**(): `default` + +Returns an algosdk KMD API client or throws an error if it's not been provided. + +#### Returns + +`default` + +#### Defined in + +[src/types/client-manager.ts:62](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L62) + +## Methods + +### getAppClientByCreatorAndName + +▸ **getAppClientByCreatorAndName**(`details`, `cachedAppLookup?`): [`ApplicationClient`](types_app_client.ApplicationClient.md) + +Returns a new `ApplicationClient` client, resolving the app by creator address and name. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `details` | [`AppClientByCreatorAndNameDetails`](../modules/types_client_manager.md#appclientbycreatorandnamedetails) | The details to resolve the app by creator address and name | +| `cachedAppLookup?` | [`AppLookup`](../interfaces/types_app.AppLookup.md) | A cached app lookup that matches a name to on-chain details; either this is needed or indexer is required to be passed in to this manager on construction. | + +#### Returns + +[`ApplicationClient`](types_app_client.ApplicationClient.md) + +The `ApplicationClient` + +#### Defined in + +[src/types/client-manager.ts:93](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L93) + +___ + +### getAppClientById + +▸ **getAppClientById**(`details`): [`ApplicationClient`](types_app_client.ApplicationClient.md) + +Returns a new `ApplicationClient` client, resolving the app by app ID. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `details` | [`AppClientByIdDetails`](../modules/types_client_manager.md#appclientbyiddetails) | The details to resolve the app by ID | + +#### Returns + +[`ApplicationClient`](types_app_client.ApplicationClient.md) + +The `ApplicationClient` + +#### Defined in + +[src/types/client-manager.ts:105](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L105) + +___ + +### getTestNetDispenser + +▸ **getTestNetDispenser**(`params?`): [`TestNetDispenserApiClient`](types_dispenser_client.TestNetDispenserApiClient.md) + +Returns a TestNet Dispenser API client. +Refer to [docs](https://github.com/algorandfoundation/algokit/blob/main/docs/testnet_api.md) on guidance to obtain an access token. + +#### Parameters + +| Name | Type | Default value | Description | +| :------ | :------ | :------ | :------ | +| `params` | ``null`` \| [`TestNetDispenserApiClientParams`](../interfaces/types_dispenser_client.TestNetDispenserApiClientParams.md) | `null` | An object containing parameters for the TestNetDispenserApiClient class. Or null if you want the client to load the access token from the environment variable `ALGOKIT_DISPENSER_ACCESS_TOKEN`. | + +#### Returns + +[`TestNetDispenserApiClient`](types_dispenser_client.TestNetDispenserApiClient.md) + +An instance of the TestNetDispenserApiClient class. + +**`Example`** + +```ts +const client = algokit.getTestNetDispenserApiClient( + { + authToken: 'your_auth_token', + requestTimeout: 15, + } +) +``` + +#### Defined in + +[src/types/client-manager.ts:83](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L83) + +___ + +### getTypedAppClientByCreatorAndName + +▸ **getTypedAppClientByCreatorAndName**\<`TClient`\>(`typedClient`, `details`, `cachedAppLookup?`): `TClient` + +Returns a new typed client, resolving the app by creator address and name. + +#### Type parameters + +| Name | +| :------ | +| `TClient` | + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `typedClient` | [`TypedAppClient`](../interfaces/types_client_manager.TypedAppClient.md)\<`TClient`\> | The typed client type to use | +| `details` | [`TypedAppClientByCreatorAndNameDetails`](../modules/types_client_manager.md#typedappclientbycreatorandnamedetails) | The details to resolve the app by creator address and name | +| `cachedAppLookup?` | [`AppLookup`](../interfaces/types_app.AppLookup.md) | A cached app lookup that matches a name to on-chain details; either this is needed or indexer is required to be passed in to this manager on construction. | + +#### Returns + +`TClient` + +The typed client instance + +#### Defined in + +[src/types/client-manager.ts:116](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L116) + +___ + +### getTypedAppClientById + +▸ **getTypedAppClientById**\<`TClient`\>(`typedClient`, `details`): `TClient` + +Returns a new typed client, resolving the app by app ID. + +#### Type parameters + +| Name | +| :------ | +| `TClient` | + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `typedClient` | [`TypedAppClient`](../interfaces/types_client_manager.TypedAppClient.md)\<`TClient`\> | The typed client type to use | +| `details` | [`TypedAppClientByIdDetails`](../modules/types_client_manager.md#typedappclientbyiddetails) | The details to resolve the app by ID | + +#### Returns + +`TClient` + +The typed client instance + +#### Defined in + +[src/types/client-manager.ts:130](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L130) diff --git a/docs/code/classes/types_composer.default.md b/docs/code/classes/types_composer.default.md new file mode 100644 index 00000000..3d031453 --- /dev/null +++ b/docs/code/classes/types_composer.default.md @@ -0,0 +1,765 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/composer](../modules/types_composer.md) / default + +# Class: default + +[types/composer](../modules/types_composer.md).default + +AlgoKit Composer helps you compose and execute transactions as a transaction group. + +Note: this class is a new Beta feature and may be subject to change. + +## Table of contents + +### Constructors + +- [constructor](types_composer.default.md#constructor) + +### Properties + +- [algod](types_composer.default.md#algod) +- [atc](types_composer.default.md#atc) +- [defaultValidityWindow](types_composer.default.md#defaultvaliditywindow) +- [getSigner](types_composer.default.md#getsigner) +- [getSuggestedParams](types_composer.default.md#getsuggestedparams) +- [txnMethodMap](types_composer.default.md#txnmethodmap) +- [txns](types_composer.default.md#txns) + +### Methods + +- [addAppCall](types_composer.default.md#addappcall) +- [addAssetConfig](types_composer.default.md#addassetconfig) +- [addAssetCreate](types_composer.default.md#addassetcreate) +- [addAssetDestroy](types_composer.default.md#addassetdestroy) +- [addAssetFreeze](types_composer.default.md#addassetfreeze) +- [addAssetOptIn](types_composer.default.md#addassetoptin) +- [addAssetTransfer](types_composer.default.md#addassettransfer) +- [addAtc](types_composer.default.md#addatc) +- [addMethodCall](types_composer.default.md#addmethodcall) +- [addOnlineKeyRegistration](types_composer.default.md#addonlinekeyregistration) +- [addPayment](types_composer.default.md#addpayment) +- [build](types_composer.default.md#build) +- [buildAppCall](types_composer.default.md#buildappcall) +- [buildAssetConfig](types_composer.default.md#buildassetconfig) +- [buildAssetCreate](types_composer.default.md#buildassetcreate) +- [buildAssetDestroy](types_composer.default.md#buildassetdestroy) +- [buildAssetFreeze](types_composer.default.md#buildassetfreeze) +- [buildAssetTransfer](types_composer.default.md#buildassettransfer) +- [buildAtc](types_composer.default.md#buildatc) +- [buildKeyReg](types_composer.default.md#buildkeyreg) +- [buildMethodCall](types_composer.default.md#buildmethodcall) +- [buildPayment](types_composer.default.md#buildpayment) +- [buildTxn](types_composer.default.md#buildtxn) +- [commonTxnBuildStep](types_composer.default.md#commontxnbuildstep) +- [execute](types_composer.default.md#execute) +- [rebuild](types_composer.default.md#rebuild) + +## Constructors + +### constructor + +• **new default**(`params`): [`default`](types_composer.default.md) + +Create an `AlgoKitComposer`. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AlgokitComposerParams`](../modules/types_composer.md#algokitcomposerparams) | The configuration for this composer | + +#### Returns + +[`default`](types_composer.default.md) + +#### Defined in + +[src/types/composer.ts:267](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L267) + +## Properties + +### algod + +• `Private` **algod**: `default` + +The algod client used by the composer. + +#### Defined in + +[src/types/composer.ts:252](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L252) + +___ + +### atc + +• `Private` **atc**: `AtomicTransactionComposer` + +The ATC used to compose the group + +#### Defined in + +[src/types/composer.ts:243](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L243) + +___ + +### defaultValidityWindow + +• `Private` **defaultValidityWindow**: `number` = `10` + +The default transaction validity window + +#### Defined in + +[src/types/composer.ts:261](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L261) + +___ + +### getSigner + +• `Private` **getSigner**: (`address`: `string`) => `TransactionSigner` + +A function that takes in an address and return a signer function for that address. + +#### Type declaration + +▸ (`address`): `TransactionSigner` + +##### Parameters + +| Name | Type | +| :------ | :------ | +| `address` | `string` | + +##### Returns + +`TransactionSigner` + +#### Defined in + +[src/types/composer.ts:258](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L258) + +___ + +### getSuggestedParams + +• `Private` **getSuggestedParams**: () => `Promise`\<`SuggestedParams`\> + +An async function that will return suggestedParams. + +#### Type declaration + +▸ (): `Promise`\<`SuggestedParams`\> + +##### Returns + +`Promise`\<`SuggestedParams`\> + +#### Defined in + +[src/types/composer.ts:255](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L255) + +___ + +### txnMethodMap + +• `Private` **txnMethodMap**: `Map`\<`string`, `ABIMethod`\> + +Map of txid to ABI method + +#### Defined in + +[src/types/composer.ts:246](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L246) + +___ + +### txns + +• `Private` **txns**: `Txn`[] = `[]` + +Transactions that have not yet been composed + +#### Defined in + +[src/types/composer.ts:249](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L249) + +## Methods + +### addAppCall + +▸ **addAppCall**(`params`): [`default`](types_composer.default.md) + +Add an application call transaction to the transaction group. + +Note: we recommend using app clients to make it easier to make app calls. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AppCallParams`](../modules/types_composer.md#appcallparams) | The application call transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:359](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L359) + +___ + +### addAssetConfig + +▸ **addAssetConfig**(`params`): [`default`](types_composer.default.md) + +Add an asset config transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AssetConfigParams`](../modules/types_composer.md#assetconfigparams) | The asset config transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:302](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L302) + +___ + +### addAssetCreate + +▸ **addAssetCreate**(`params`): [`default`](types_composer.default.md) + +Add an asset create transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AssetCreateParams`](../modules/types_composer.md#assetcreateparams) | The asset create transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:291](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L291) + +___ + +### addAssetDestroy + +▸ **addAssetDestroy**(`params`): [`default`](types_composer.default.md) + +Add an asset destroy transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AssetDestroyParams`](../modules/types_composer.md#assetdestroyparams) | The asset destroy transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:324](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L324) + +___ + +### addAssetFreeze + +▸ **addAssetFreeze**(`params`): [`default`](types_composer.default.md) + +Add an asset freeze transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AssetFreezeParams`](../modules/types_composer.md#assetfreezeparams) | The asset freeze transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:313](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L313) + +___ + +### addAssetOptIn + +▸ **addAssetOptIn**(`params`): [`default`](types_composer.default.md) + +Add an asset opt-in transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AssetOptInParams`](../modules/types_composer.md#assetoptinparams) | The asset opt-in transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:346](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L346) + +___ + +### addAssetTransfer + +▸ **addAssetTransfer**(`params`): [`default`](types_composer.default.md) + +Add an asset transfer transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`AssetTransferParams`](../modules/types_composer.md#assettransferparams) | The asset transfer transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:335](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L335) + +___ + +### addAtc + +▸ **addAtc**(`atc`): [`default`](types_composer.default.md) + +Add the transactions within an `AtomicTransactionComposer` to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `atc` | `AtomicTransactionComposer` | The `AtomicTransactionComposer` to build transactions from and add to the group | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:393](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L393) + +___ + +### addMethodCall + +▸ **addMethodCall**(`params`): [`default`](types_composer.default.md) + +Add an ABI method application call transaction to the transaction group. + +Note: we recommend using app clients to make it easier to make app calls. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`MethodCallParams`](../modules/types_composer.md#methodcallparams) | The ABI method application call transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:372](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L372) + +___ + +### addOnlineKeyRegistration + +▸ **addOnlineKeyRegistration**(`params`): [`default`](types_composer.default.md) + +Add an online key registration transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`OnlineKeyRegistrationParams`](../modules/types_composer.md#onlinekeyregistrationparams) | The online key registration transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:382](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L382) + +___ + +### addPayment + +▸ **addPayment**(`params`): [`default`](types_composer.default.md) + +Add a payment transaction to the transaction group. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params` | [`PaymentParams`](../modules/types_composer.md#paymentparams) | The payment transaction parameters | + +#### Returns + +[`default`](types_composer.default.md) + +The composer so you can chain method calls + +#### Defined in + +[src/types/composer.ts:280](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L280) + +___ + +### build + +▸ **build**(): `Promise`\<\{ `atc`: `AtomicTransactionComposer` ; `transactions`: `TransactionWithSigner`[] }\> + +Compose all of the transactions in a single atomic transaction group and an atomic transaction composer. + +You can then use the transactions standalone, or use the composer to execute or simulate the transactions. + +#### Returns + +`Promise`\<\{ `atc`: `AtomicTransactionComposer` ; `transactions`: `TransactionWithSigner`[] }\> + +The built atomic transaction composer and the transactions + +#### Defined in + +[src/types/composer.ts:711](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L711) + +___ + +### buildAppCall + +▸ **buildAppCall**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`AppCallParams`](../modules/types_composer.md#appcallparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:590](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L590) + +___ + +### buildAssetConfig + +▸ **buildAssetConfig**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`AssetConfigParams`](../modules/types_composer.md#assetconfigparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:539](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L539) + +___ + +### buildAssetCreate + +▸ **buildAssetCreate**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`AssetCreateParams`](../modules/types_composer.md#assetcreateparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:519](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L519) + +___ + +### buildAssetDestroy + +▸ **buildAssetDestroy**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`AssetDestroyParams`](../modules/types_composer.md#assetdestroyparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:554](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L554) + +___ + +### buildAssetFreeze + +▸ **buildAssetFreeze**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`AssetFreezeParams`](../modules/types_composer.md#assetfreezeparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:564](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L564) + +___ + +### buildAssetTransfer + +▸ **buildAssetTransfer**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`AssetTransferParams`](../modules/types_composer.md#assettransferparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:576](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L576) + +___ + +### buildAtc + +▸ **buildAtc**(`atc`): `TransactionWithSigner`[] + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `atc` | `AtomicTransactionComposer` | + +#### Returns + +`TransactionWithSigner`[] + +#### Defined in + +[src/types/composer.ts:398](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L398) + +___ + +### buildKeyReg + +▸ **buildKeyReg**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`OnlineKeyRegistrationParams`](../modules/types_composer.md#onlinekeyregistrationparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:630](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L630) + +___ + +### buildMethodCall + +▸ **buildMethodCall**(`params`, `suggestedParams`): `Promise`\<`TransactionWithSigner`[]\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`MethodCallParams`](../modules/types_composer.md#methodcallparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Promise`\<`TransactionWithSigner`[]\> + +#### Defined in + +[src/types/composer.ts:446](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L446) + +___ + +### buildPayment + +▸ **buildPayment**(`params`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`PaymentParams`](../modules/types_composer.md#paymentparams) | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:507](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L507) + +___ + +### buildTxn + +▸ **buildTxn**(`txn`, `suggestedParams`): `Promise`\<`TransactionWithSigner`[]\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `txn` | `Txn` | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Promise`\<`TransactionWithSigner`[]\> + +#### Defined in + +[src/types/composer.ts:648](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L648) + +___ + +### commonTxnBuildStep + +▸ **commonTxnBuildStep**(`params`, `txn`, `suggestedParams`): `Transaction` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `params` | [`CommonTransactionParams`](../modules/types_composer.md#commontransactionparams) | +| `txn` | `Transaction` | +| `suggestedParams` | `SuggestedParams` | + +#### Returns + +`Transaction` + +#### Defined in + +[src/types/composer.ts:412](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L412) + +___ + +### execute + +▸ **execute**(`params?`): `Promise`\<[`SendAtomicTransactionComposerResults`](../interfaces/types_transaction.SendAtomicTransactionComposerResults.md)\> + +Compose the atomic transaction group and send it to the network + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `params?` | [`ExecuteParams`](../interfaces/types_composer.ExecuteParams.md) | The parameters to control execution with | + +#### Returns + +`Promise`\<[`SendAtomicTransactionComposerResults`](../interfaces/types_transaction.SendAtomicTransactionComposerResults.md)\> + +The execution result + +#### Defined in + +[src/types/composer.ts:753](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L753) + +___ + +### rebuild + +▸ **rebuild**(): `Promise`\<\{ `atc`: `AtomicTransactionComposer` ; `transactions`: `TransactionWithSigner`[] }\> + +Rebuild the group, discarding any previously built transactions. +This will potentially cause new signers and suggested params to be used if the callbacks return a new value compared to the first build. + +#### Returns + +`Promise`\<\{ `atc`: `AtomicTransactionComposer` ; `transactions`: `TransactionWithSigner`[] }\> + +The newly built atomic transaction composer and the transactions + +#### Defined in + +[src/types/composer.ts:743](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L743) diff --git a/docs/code/interfaces/types_account.AccountConfig.md b/docs/code/interfaces/types_account.AccountConfig.md index 0f3daf45..cd906e66 100644 --- a/docs/code/interfaces/types_account.AccountConfig.md +++ b/docs/code/interfaces/types_account.AccountConfig.md @@ -25,7 +25,7 @@ Mnemonic for an account #### Defined in -[src/types/account.ts:120](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L120) +[src/types/account.ts:121](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L121) ___ @@ -37,7 +37,7 @@ Account name used to retrieve config #### Defined in -[src/types/account.ts:124](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L124) +[src/types/account.ts:125](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L125) ___ @@ -49,7 +49,7 @@ Address of a rekeyed account #### Defined in -[src/types/account.ts:122](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L122) +[src/types/account.ts:123](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L123) ___ @@ -63,4 +63,4 @@ Renamed to senderAddress in 2.3.1 #### Defined in -[src/types/account.ts:127](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L127) +[src/types/account.ts:128](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L128) diff --git a/docs/code/interfaces/types_account.TransactionSignerAccount.md b/docs/code/interfaces/types_account.TransactionSignerAccount.md index 6f15c22b..469aaecd 100644 --- a/docs/code/interfaces/types_account.TransactionSignerAccount.md +++ b/docs/code/interfaces/types_account.TransactionSignerAccount.md @@ -21,7 +21,7 @@ A wrapper around `TransactionSigner` that also has the sender address. #### Defined in -[src/types/account.ts:113](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L113) +[src/types/account.ts:114](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L114) ___ @@ -31,4 +31,4 @@ ___ #### Defined in -[src/types/account.ts:114](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L114) +[src/types/account.ts:115](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L115) diff --git a/docs/code/interfaces/types_client_manager.AlgoSdkClients.md b/docs/code/interfaces/types_client_manager.AlgoSdkClients.md new file mode 100644 index 00000000..93a5a0bf --- /dev/null +++ b/docs/code/interfaces/types_client_manager.AlgoSdkClients.md @@ -0,0 +1,51 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/client-manager](../modules/types_client_manager.md) / AlgoSdkClients + +# Interface: AlgoSdkClients + +[types/client-manager](../modules/types_client_manager.md).AlgoSdkClients + +Clients from algosdk that interact with the official Algorand APIs + +## Table of contents + +### Properties + +- [algod](types_client_manager.AlgoSdkClients.md#algod) +- [indexer](types_client_manager.AlgoSdkClients.md#indexer) +- [kmd](types_client_manager.AlgoSdkClients.md#kmd) + +## Properties + +### algod + +• **algod**: `default` + +Algod client, see https://developer.algorand.org/docs/rest-apis/algod/ + +#### Defined in + +[src/types/client-manager.ts:19](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L19) + +___ + +### indexer + +• `Optional` **indexer**: `default` + +Optional indexer client, see https://developer.algorand.org/docs/rest-apis/indexer/ + +#### Defined in + +[src/types/client-manager.ts:21](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L21) + +___ + +### kmd + +• `Optional` **kmd**: `default` + +Optional KMD client, see https://developer.algorand.org/docs/rest-apis/kmd/ + +#### Defined in + +[src/types/client-manager.ts:23](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L23) diff --git a/docs/code/interfaces/types_client_manager.TypedAppClient.md b/docs/code/interfaces/types_client_manager.TypedAppClient.md new file mode 100644 index 00000000..262ad3c2 --- /dev/null +++ b/docs/code/interfaces/types_client_manager.TypedAppClient.md @@ -0,0 +1,40 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/client-manager](../modules/types_client_manager.md) / TypedAppClient + +# Interface: TypedAppClient\ + +[types/client-manager](../modules/types_client_manager.md).TypedAppClient + +Interface to identify a typed client that can be used to interact with an application. + +## Type parameters + +| Name | +| :------ | +| `TClient` | + +## Table of contents + +### Constructors + +- [constructor](types_client_manager.TypedAppClient.md#constructor) + +## Constructors + +### constructor + +• **new TypedAppClient**(`details`, `algod`): `TClient` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `details` | [`AppDetails`](../modules/types_app_client.md#appdetails) | +| `algod` | `default` | + +#### Returns + +`TClient` + +#### Defined in + +[src/types/client-manager.ts:139](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L139) diff --git a/docs/code/interfaces/types_composer.ExecuteParams.md b/docs/code/interfaces/types_composer.ExecuteParams.md new file mode 100644 index 00000000..00eb58d2 --- /dev/null +++ b/docs/code/interfaces/types_composer.ExecuteParams.md @@ -0,0 +1,38 @@ +[@algorandfoundation/algokit-utils](../README.md) / [types/composer](../modules/types_composer.md) / ExecuteParams + +# Interface: ExecuteParams + +[types/composer](../modules/types_composer.md).ExecuteParams + +Parameters to configure transaction execution. + +## Table of contents + +### Properties + +- [maxRoundsToWaitForConfirmation](types_composer.ExecuteParams.md#maxroundstowaitforconfirmation) +- [suppressLog](types_composer.ExecuteParams.md#suppresslog) + +## Properties + +### maxRoundsToWaitForConfirmation + +• `Optional` **maxRoundsToWaitForConfirmation**: `number` + +The number of rounds to wait for confirmation. By default until the latest lastValid has past. + +#### Defined in + +[src/types/composer.ts:218](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L218) + +___ + +### suppressLog + +• `Optional` **suppressLog**: `boolean` + +Whether to suppress log messages from transaction send, default: do not suppress + +#### Defined in + +[src/types/composer.ts:220](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L220) diff --git a/docs/code/interfaces/types_network_client.AlgoConfig.md b/docs/code/interfaces/types_network_client.AlgoConfig.md index 8936facf..10873726 100644 --- a/docs/code/interfaces/types_network_client.AlgoConfig.md +++ b/docs/code/interfaces/types_network_client.AlgoConfig.md @@ -30,7 +30,7 @@ ___ ### indexerConfig -• **indexerConfig**: [`AlgoClientConfig`](types_network_client.AlgoClientConfig.md) +• `Optional` **indexerConfig**: [`AlgoClientConfig`](types_network_client.AlgoClientConfig.md) Indexer client configuration @@ -42,7 +42,7 @@ ___ ### kmdConfig -• **kmdConfig**: [`AlgoClientConfig`](types_network_client.AlgoClientConfig.md) +• `Optional` **kmdConfig**: [`AlgoClientConfig`](types_network_client.AlgoClientConfig.md) Kmd configuration diff --git a/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md b/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md index 181ab1ae..45698c93 100644 --- a/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md +++ b/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md @@ -33,7 +33,7 @@ Testing framework agnostic handler method to run after each test to reset the lo #### Defined in -[src/types/testing.ts:104](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L104) +[src/types/testing.ts:111](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L111) ___ @@ -53,7 +53,7 @@ Testing framework agnostic handler method to run before each test to prepare the #### Defined in -[src/types/testing.ts:100](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L100) +[src/types/testing.ts:107](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L107) ## Accessors @@ -69,4 +69,4 @@ The test logger instance for the current test #### Defined in -[src/types/testing.ts:96](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L96) +[src/types/testing.ts:103](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L103) diff --git a/docs/code/interfaces/types_testing.AlgorandFixture.md b/docs/code/interfaces/types_testing.AlgorandFixture.md index c0a610d0..54f1542f 100644 --- a/docs/code/interfaces/types_testing.AlgorandFixture.md +++ b/docs/code/interfaces/types_testing.AlgorandFixture.md @@ -14,6 +14,7 @@ An Algorand automated testing fixture ### Accessors +- [algorand](types_testing.AlgorandFixture.md#algorand) - [context](types_testing.AlgorandFixture.md#context) ## Properties @@ -34,10 +35,26 @@ Testing framework agnostic handler method to run before each test to prepare the #### Defined in -[src/types/testing.ts:78](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L78) +[src/types/testing.ts:85](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L85) ## Accessors +### algorand + +• `get` **algorand**(): [`AlgorandClient`](../classes/types_algorand_client.AlgorandClient.md) + +Retrieve an `AlgorandClient` loaded with the current context, including testAccount and any generated accounts loaded as signers. + +#### Returns + +[`AlgorandClient`](../classes/types_algorand_client.AlgorandClient.md) + +#### Defined in + +[src/types/testing.ts:80](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L80) + +___ + ### context • `get` **context**(): [`AlgorandTestAutomationContext`](types_testing.AlgorandTestAutomationContext.md) @@ -59,4 +76,4 @@ test('My test', () => { #### Defined in -[src/types/testing.ts:73](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L73) +[src/types/testing.ts:75](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L75) diff --git a/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md b/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md index 0147d43b..b97a0e70 100644 --- a/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md +++ b/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md @@ -41,7 +41,7 @@ Optional override for how to get an account; this allows you to retrieve account #### Defined in -[src/types/testing.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L58) +[src/types/testing.ts:60](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L60) ___ @@ -53,7 +53,7 @@ An optional algod client, if not specified then it will create one against envir #### Defined in -[src/types/testing.ts:50](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L50) +[src/types/testing.ts:52](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L52) ___ @@ -65,7 +65,7 @@ An optional indexer client, if not specified then it will create one against env #### Defined in -[src/types/testing.ts:52](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L52) +[src/types/testing.ts:54](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L54) ___ @@ -77,7 +77,7 @@ An optional kmd client, if not specified then it will create one against environ #### Defined in -[src/types/testing.ts:54](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L54) +[src/types/testing.ts:56](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L56) ___ @@ -89,4 +89,4 @@ The amount of funds to allocate to the default testing account, if not specified #### Defined in -[src/types/testing.ts:56](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L56) +[src/types/testing.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L58) diff --git a/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md b/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md index 5389d95c..6e986be1 100644 --- a/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md +++ b/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md @@ -29,19 +29,19 @@ Algod client instance that will log transactions in `transactionLogger` #### Defined in -[src/types/testing.ts:18](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L18) +[src/types/testing.ts:20](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L20) ___ ### generateAccount -• **generateAccount**: (`params`: [`GetTestAccountParams`](types_testing.GetTestAccountParams.md)) => `Promise`\<`default`\> +• **generateAccount**: (`params`: [`GetTestAccountParams`](types_testing.GetTestAccountParams.md)) => `Promise`\<`default` & [`TransactionSignerAccount`](types_account.TransactionSignerAccount.md)\> Generate and fund an additional ephemerally created account #### Type declaration -▸ (`params`): `Promise`\<`default`\> +▸ (`params`): `Promise`\<`default` & [`TransactionSignerAccount`](types_account.TransactionSignerAccount.md)\> ##### Parameters @@ -51,11 +51,11 @@ Generate and fund an additional ephemerally created account ##### Returns -`Promise`\<`default`\> +`Promise`\<`default` & [`TransactionSignerAccount`](types_account.TransactionSignerAccount.md)\> #### Defined in -[src/types/testing.ts:28](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L28) +[src/types/testing.ts:30](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L30) ___ @@ -67,7 +67,7 @@ Indexer client instance #### Defined in -[src/types/testing.ts:20](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L20) +[src/types/testing.ts:22](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L22) ___ @@ -79,19 +79,19 @@ KMD client instance #### Defined in -[src/types/testing.ts:22](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L22) +[src/types/testing.ts:24](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L24) ___ ### testAccount -• **testAccount**: `default` +• **testAccount**: `default` & [`TransactionSignerAccount`](types_account.TransactionSignerAccount.md) Default, funded test account that is ephemerally created #### Defined in -[src/types/testing.ts:26](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L26) +[src/types/testing.ts:28](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L28) ___ @@ -103,7 +103,7 @@ Transaction logger that will log transaction IDs for all transactions issued by #### Defined in -[src/types/testing.ts:24](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L24) +[src/types/testing.ts:26](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L26) ___ @@ -123,7 +123,7 @@ Wait for the indexer to catch up with all transactions logged by `transactionLog #### Defined in -[src/types/testing.ts:30](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L30) +[src/types/testing.ts:32](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L32) ___ @@ -149,4 +149,4 @@ Wait for the indexer to catch up with the given transaction ID #### Defined in -[src/types/testing.ts:32](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L32) +[src/types/testing.ts:34](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L34) diff --git a/docs/code/interfaces/types_testing.GetTestAccountParams.md b/docs/code/interfaces/types_testing.GetTestAccountParams.md index d4b12c00..a62d36ba 100644 --- a/docs/code/interfaces/types_testing.GetTestAccountParams.md +++ b/docs/code/interfaces/types_testing.GetTestAccountParams.md @@ -39,7 +39,7 @@ Optional override for how to get an account; this allows you to retrieve account #### Defined in -[src/types/testing.ts:44](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L44) +[src/types/testing.ts:46](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L46) ___ @@ -51,7 +51,7 @@ Initial funds to ensure the account has #### Defined in -[src/types/testing.ts:40](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L40) +[src/types/testing.ts:42](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L42) ___ @@ -63,4 +63,4 @@ Whether to suppress the log (which includes a mnemonic) or not (default: do not #### Defined in -[src/types/testing.ts:42](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L42) +[src/types/testing.ts:44](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L44) diff --git a/docs/code/interfaces/types_testing.LogSnapshotConfig.md b/docs/code/interfaces/types_testing.LogSnapshotConfig.md index 5d696ee3..855b65e1 100644 --- a/docs/code/interfaces/types_testing.LogSnapshotConfig.md +++ b/docs/code/interfaces/types_testing.LogSnapshotConfig.md @@ -26,7 +26,7 @@ Any accounts/addresses to replace the address for predictably #### Defined in -[src/types/testing.ts:89](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L89) +[src/types/testing.ts:96](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L96) ___ @@ -38,7 +38,7 @@ Any app IDs to replace predictably #### Defined in -[src/types/testing.ts:91](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L91) +[src/types/testing.ts:98](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L98) ___ @@ -50,4 +50,4 @@ Any transaction IDs or transactions to replace the ID for predictably #### Defined in -[src/types/testing.ts:87](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L87) +[src/types/testing.ts:94](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L94) diff --git a/docs/code/interfaces/types_transaction.AtomicTransactionComposerToSend.md b/docs/code/interfaces/types_transaction.AtomicTransactionComposerToSend.md index 2c7aea07..b791dec7 100644 --- a/docs/code/interfaces/types_transaction.AtomicTransactionComposerToSend.md +++ b/docs/code/interfaces/types_transaction.AtomicTransactionComposerToSend.md @@ -23,7 +23,7 @@ The `AtomicTransactionComposer` with transactions loaded to send #### Defined in -[src/types/transaction.ts:128](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L128) +[src/types/transaction.ts:132](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L132) ___ @@ -35,4 +35,4 @@ Any parameters to control the semantics of the send to the network #### Defined in -[src/types/transaction.ts:130](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L130) +[src/types/transaction.ts:134](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L134) diff --git a/docs/code/interfaces/types_transaction.ConfirmedTransactionResult.md b/docs/code/interfaces/types_transaction.ConfirmedTransactionResult.md index 0f23479c..4b5ad2b2 100644 --- a/docs/code/interfaces/types_transaction.ConfirmedTransactionResult.md +++ b/docs/code/interfaces/types_transaction.ConfirmedTransactionResult.md @@ -33,7 +33,7 @@ The response from sending and waiting for the transaction #### Defined in -[src/types/transaction.ts:79](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L79) +[src/types/transaction.ts:83](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L83) ___ diff --git a/docs/code/interfaces/types_transaction.ConfirmedTransactionResults.md b/docs/code/interfaces/types_transaction.ConfirmedTransactionResults.md index 46a11be8..be464e70 100644 --- a/docs/code/interfaces/types_transaction.ConfirmedTransactionResults.md +++ b/docs/code/interfaces/types_transaction.ConfirmedTransactionResults.md @@ -37,7 +37,7 @@ The response from sending and waiting for the primary transaction #### Defined in -[src/types/transaction.ts:85](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L85) +[src/types/transaction.ts:89](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L89) ___ @@ -53,7 +53,7 @@ The response from sending and waiting for the transactions #### Defined in -[src/types/transaction.ts:87](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L87) +[src/types/transaction.ts:91](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L91) ___ diff --git a/docs/code/interfaces/types_transaction.SendAtomicTransactionComposerResults.md b/docs/code/interfaces/types_transaction.SendAtomicTransactionComposerResults.md index e4a01ad3..584c6af4 100644 --- a/docs/code/interfaces/types_transaction.SendAtomicTransactionComposerResults.md +++ b/docs/code/interfaces/types_transaction.SendAtomicTransactionComposerResults.md @@ -26,18 +26,18 @@ The result of preparing and/or sending multiple transactions using an `AtomicTra ### confirmations -• `Optional` **confirmations**: `PendingTransactionResponse`[] +• **confirmations**: `PendingTransactionResponse`[] The responses if the transactions were sent and waited for, the index of the confirmation will match the index of the underlying transaction -#### Inherited from +#### Overrides [SendTransactionResults](types_transaction.SendTransactionResults.md).[confirmations](types_transaction.SendTransactionResults.md#confirmations) #### Defined in -[src/types/transaction.ts:63](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L63) +[src/types/transaction.ts:77](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L77) ___ diff --git a/docs/code/interfaces/types_transaction.TransactionGroupToSend.md b/docs/code/interfaces/types_transaction.TransactionGroupToSend.md index 7762ad5e..3841e720 100644 --- a/docs/code/interfaces/types_transaction.TransactionGroupToSend.md +++ b/docs/code/interfaces/types_transaction.TransactionGroupToSend.md @@ -25,7 +25,7 @@ Any parameters to control the semantics of the send to the network #### Defined in -[src/types/transaction.ts:115](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L115) +[src/types/transaction.ts:119](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L119) ___ @@ -37,7 +37,7 @@ Optional signer to pass in, required if at least one transaction provided is jus #### Defined in -[src/types/transaction.ts:122](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L122) +[src/types/transaction.ts:126](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L126) ___ @@ -51,4 +51,4 @@ The list of transactions to send, which can either be a raw transaction (in whic #### Defined in -[src/types/transaction.ts:120](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L120) +[src/types/transaction.ts:124](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L124) diff --git a/docs/code/interfaces/types_transaction.TransactionToSign.md b/docs/code/interfaces/types_transaction.TransactionToSign.md index d727cf10..c28fa19f 100644 --- a/docs/code/interfaces/types_transaction.TransactionToSign.md +++ b/docs/code/interfaces/types_transaction.TransactionToSign.md @@ -23,7 +23,7 @@ The account to use to sign the transaction, either an account (with private key #### Defined in -[src/types/transaction.ts:107](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L107) +[src/types/transaction.ts:111](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L111) ___ @@ -35,4 +35,4 @@ The unsigned transaction to sign and send #### Defined in -[src/types/transaction.ts:105](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L105) +[src/types/transaction.ts:109](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L109) diff --git a/docs/code/modules/index.md b/docs/code/modules/index.md index cf86f621..8bb66a9c 100644 --- a/docs/code/modules/index.md +++ b/docs/code/modules/index.md @@ -4,6 +4,11 @@ ## Table of contents +### References + +- [AlgorandClient](index.md#algorandclient) +- [SendSingleTransactionResult](index.md#sendsingletransactionresult) + ### Variables - [Config](index.md#config) @@ -35,7 +40,9 @@ - [getAccount](index.md#getaccount) - [getAccountAddressAsString](index.md#getaccountaddressasstring) - [getAccountAddressAsUint8Array](index.md#getaccountaddressasuint8array) +- [getAccountAssetInformation](index.md#getaccountassetinformation) - [getAccountConfigFromEnvironment](index.md#getaccountconfigfromenvironment) +- [getAccountInformation](index.md#getaccountinformation) - [getAlgoClient](index.md#getalgoclient) - [getAlgoIndexerClient](index.md#getalgoindexerclient) - [getAlgoKmdClient](index.md#getalgokmdclient) @@ -106,6 +113,18 @@ - [updateApp](index.md#updateapp) - [waitForConfirmation](index.md#waitforconfirmation) +## References + +### AlgorandClient + +Re-exports [AlgorandClient](../classes/types_algorand_client.AlgorandClient.md) + +___ + +### SendSingleTransactionResult + +Re-exports [SendSingleTransactionResult](types_algorand_client.md#sendsingletransactionresult) + ## Variables ### Config @@ -813,7 +832,7 @@ Returns the string address of an Algorand account from a base64 encoded version #### Defined in -[src/account/account.ts:127](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L127) +[src/account/account.ts:128](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L128) ___ @@ -835,7 +854,43 @@ Returns an account's address as a byte array #### Defined in -[src/account/account.ts:119](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L119) +[src/account/account.ts:120](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L120) + +___ + +### getAccountAssetInformation + +▸ **getAccountAssetInformation**(`sender`, `assetId`, `algod`): `Promise`\<[`AccountAssetInformation`](types_account.md#accountassetinformation)\> + +Returns the given sender account's asset holding for a given asset. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` \| [`SendTransactionFrom`](types_transaction.md#sendtransactionfrom) | The address of the sender/account to look up | +| `assetId` | `number` \| `bigint` | The ID of the asset to return a holding for | +| `algod` | `default` | The algod instance | + +#### Returns + +`Promise`\<[`AccountAssetInformation`](types_account.md#accountassetinformation)\> + +The account asset holding information + +**`Example`** + +```typescript +const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; +const assetId = 123345; +const accountInfo = await account.getAccountAssetInformation(address, assetId, algod); +``` + +[Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddressassetsasset-id) + +#### Defined in + +[src/account/account.ts:187](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L187) ___ @@ -872,6 +927,40 @@ environment variables ___ +### getAccountInformation + +▸ **getAccountInformation**(`sender`, `algod`): `Promise`\<[`AccountInformation`](types_account.md#accountinformation)\> + +Returns the given sender account's current status, balance and spendable amounts. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `sender` | `string` \| [`SendTransactionFrom`](types_transaction.md#sendtransactionfrom) | The address of the sender/account to look up | +| `algod` | `default` | The algod instance | + +#### Returns + +`Promise`\<[`AccountInformation`](types_account.md#accountinformation)\> + +The account information + +**`Example`** + +```typescript +const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; +const accountInfo = await account.getInformation(address, algod); +``` + +[Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddress) + +#### Defined in + +[src/account/account.ts:146](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L146) + +___ + ### getAlgoClient ▸ **getAlgoClient**(`config?`): `Algodv2` @@ -2132,7 +2221,7 @@ If not running against LocalNet then it will use proces.env.MY_ACCOUNT_MNEMONIC #### Defined in -[src/account/account.ts:87](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L87) +[src/account/account.ts:88](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L88) ___ @@ -2157,7 +2246,7 @@ A multisig account wrapper #### Defined in -[src/account/account.ts:23](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L23) +[src/account/account.ts:24](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L24) ___ @@ -2332,7 +2421,7 @@ This is a wrapper around algosdk.generateAccount to provide a more friendly/obvi #### Defined in -[src/account/account.ts:52](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L52) +[src/account/account.ts:53](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L53) ___ @@ -2390,7 +2479,7 @@ The SigningAccount wrapper #### Defined in -[src/account/account.ts:33](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L33) +[src/account/account.ts:34](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L34) ___ @@ -2660,7 +2749,7 @@ The SigningAccount wrapper #### Defined in -[src/account/account.ts:43](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L43) +[src/account/account.ts:44](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/account/account.ts#L44) ___ diff --git a/docs/code/modules/testing.md b/docs/code/modules/testing.md index d91ad713..59ba2da4 100644 --- a/docs/code/modules/testing.md +++ b/docs/code/modules/testing.md @@ -86,7 +86,7 @@ test('My test', async () => { #### Defined in -[src/testing/fixtures/algorand-fixture.ts:38](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L38) +[src/testing/fixtures/algorand-fixture.ts:39](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L39) ▸ **algorandFixture**(`fixtureConfig`, `config`): [`AlgorandFixture`](../interfaces/types_testing.AlgorandFixture.md) @@ -124,7 +124,7 @@ test('My test', async () => { #### Defined in -[src/testing/fixtures/algorand-fixture.ts:63](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L63) +[src/testing/fixtures/algorand-fixture.ts:64](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L64) ___ diff --git a/docs/code/modules/types_account.md b/docs/code/modules/types_account.md index 5330b79c..286e2cfa 100644 --- a/docs/code/modules/types_account.md +++ b/docs/code/modules/types_account.md @@ -14,10 +14,48 @@ - [AccountConfig](../interfaces/types_account.AccountConfig.md) - [TransactionSignerAccount](../interfaces/types_account.TransactionSignerAccount.md) +### Type Aliases + +- [AccountAssetInformation](types_account.md#accountassetinformation) +- [AccountInformation](types_account.md#accountinformation) + ### Variables - [DISPENSER\_ACCOUNT](types_account.md#dispenser_account) +## Type Aliases + +### AccountAssetInformation + +Ƭ **AccountAssetInformation**: `Object` + +Account asset holding information at a given round. + +#### Type declaration + +| Name | Type | Description | +| :------ | :------ | :------ | +| `assetId` | `bigint` | The ID of the asset held. | +| `balance` | `bigint` | The current balance of that asset holding. | +| `frozen` | `boolean` | Whether or not the asset is frozen for the account. | +| `round` | `bigint` | The round as at which the holding was correct. | + +#### Defined in + +[src/types/account.ts:137](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L137) + +___ + +### AccountInformation + +Ƭ **AccountInformation**: `Omit`\<`NumberConverter`\<`AccountInformationModel`\>, ``"get_obj_for_encoding"``\> + +Account information at a given round. + +#### Defined in + +[src/types/account.ts:134](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L134) + ## Variables ### DISPENSER\_ACCOUNT @@ -28,4 +66,4 @@ The account name identifier used for fund dispensing in test environments #### Defined in -[src/types/account.ts:10](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L10) +[src/types/account.ts:11](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account.ts#L11) diff --git a/docs/code/modules/types_account_manager.md b/docs/code/modules/types_account_manager.md new file mode 100644 index 00000000..87fb97aa --- /dev/null +++ b/docs/code/modules/types_account_manager.md @@ -0,0 +1,9 @@ +[@algorandfoundation/algokit-utils](../README.md) / types/account-manager + +# Module: types/account-manager + +## Table of contents + +### Classes + +- [AccountManager](../classes/types_account_manager.AccountManager.md) diff --git a/docs/code/modules/types_algorand_client.md b/docs/code/modules/types_algorand_client.md new file mode 100644 index 00000000..c5f8a275 --- /dev/null +++ b/docs/code/modules/types_algorand_client.md @@ -0,0 +1,35 @@ +[@algorandfoundation/algokit-utils](../README.md) / types/algorand-client + +# Module: types/algorand-client + +## Table of contents + +### References + +- [default](types_algorand_client.md#default) + +### Classes + +- [AlgorandClient](../classes/types_algorand_client.AlgorandClient.md) + +### Type Aliases + +- [SendSingleTransactionResult](types_algorand_client.md#sendsingletransactionresult) + +## References + +### default + +Renames and re-exports [AlgorandClient](../classes/types_algorand_client.AlgorandClient.md) + +## Type Aliases + +### SendSingleTransactionResult + +Ƭ **SendSingleTransactionResult**: [`SendAtomicTransactionComposerResults`](../interfaces/types_transaction.SendAtomicTransactionComposerResults.md) & [`ConfirmedTransactionResult`](../interfaces/types_transaction.ConfirmedTransactionResult.md) + +Result from sending a single transaction. + +#### Defined in + +[src/types/algorand-client.ts:13](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algorand-client.ts#L13) diff --git a/docs/code/modules/types_algorand_client_spec.md b/docs/code/modules/types_algorand_client_spec.md new file mode 100644 index 00000000..2a3fb2a0 --- /dev/null +++ b/docs/code/modules/types_algorand_client_spec.md @@ -0,0 +1,3 @@ +[@algorandfoundation/algokit-utils](../README.md) / types/algorand-client.spec + +# Module: types/algorand-client.spec diff --git a/docs/code/modules/types_client_manager.md b/docs/code/modules/types_client_manager.md new file mode 100644 index 00000000..d87298d2 --- /dev/null +++ b/docs/code/modules/types_client_manager.md @@ -0,0 +1,69 @@ +[@algorandfoundation/algokit-utils](../README.md) / types/client-manager + +# Module: types/client-manager + +## Table of contents + +### Classes + +- [ClientManager](../classes/types_client_manager.ClientManager.md) + +### Interfaces + +- [AlgoSdkClients](../interfaces/types_client_manager.AlgoSdkClients.md) +- [TypedAppClient](../interfaces/types_client_manager.TypedAppClient.md) + +### Type Aliases + +- [AppClientByCreatorAndNameDetails](types_client_manager.md#appclientbycreatorandnamedetails) +- [AppClientByIdDetails](types_client_manager.md#appclientbyiddetails) +- [TypedAppClientByCreatorAndNameDetails](types_client_manager.md#typedappclientbycreatorandnamedetails) +- [TypedAppClientByIdDetails](types_client_manager.md#typedappclientbyiddetails) + +## Type Aliases + +### AppClientByCreatorAndNameDetails + +Ƭ **AppClientByCreatorAndNameDetails**: [`AppSpecAppDetailsBase`](types_app_client.md#appspecappdetailsbase) & [`AppDetailsBase`](types_app_client.md#appdetailsbase) & `Omit`\<[`ResolveAppByCreatorAndNameBase`](types_app_client.md#resolveappbycreatorandnamebase), ``"findExistingUsing"``\> + +Details to resolve an app client by creator address and name. + +#### Defined in + +[src/types/client-manager.ts:145](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L145) + +___ + +### AppClientByIdDetails + +Ƭ **AppClientByIdDetails**: [`AppSpecAppDetailsBase`](types_app_client.md#appspecappdetailsbase) & [`AppDetailsBase`](types_app_client.md#appdetailsbase) & [`ResolveAppByIdBase`](../interfaces/types_app_client.ResolveAppByIdBase.md) + +Details to resolve an app client by app ID. + +#### Defined in + +[src/types/client-manager.ts:157](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L157) + +___ + +### TypedAppClientByCreatorAndNameDetails + +Ƭ **TypedAppClientByCreatorAndNameDetails**: [`AppDetailsBase`](types_app_client.md#appdetailsbase) & `Omit`\<[`ResolveAppByCreatorAndNameBase`](types_app_client.md#resolveappbycreatorandnamebase), ``"findExistingUsing"``\> + +Details to resolve a typed app creator address and name. + +#### Defined in + +[src/types/client-manager.ts:152](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L152) + +___ + +### TypedAppClientByIdDetails + +Ƭ **TypedAppClientByIdDetails**: [`AppDetailsBase`](types_app_client.md#appdetailsbase) & [`ResolveAppByIdBase`](../interfaces/types_app_client.ResolveAppByIdBase.md) + +Details to resolve a typed app by app ID. + +#### Defined in + +[src/types/client-manager.ts:162](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/client-manager.ts#L162) diff --git a/docs/code/modules/types_composer.md b/docs/code/modules/types_composer.md new file mode 100644 index 00000000..e3fb37a1 --- /dev/null +++ b/docs/code/modules/types_composer.md @@ -0,0 +1,197 @@ +[@algorandfoundation/algokit-utils](../README.md) / types/composer + +# Module: types/composer + +## Table of contents + +### Classes + +- [default](../classes/types_composer.default.md) + +### Interfaces + +- [ExecuteParams](../interfaces/types_composer.ExecuteParams.md) + +### Type Aliases + +- [AlgokitComposerParams](types_composer.md#algokitcomposerparams) +- [AppCallParams](types_composer.md#appcallparams) +- [AssetConfigParams](types_composer.md#assetconfigparams) +- [AssetCreateParams](types_composer.md#assetcreateparams) +- [AssetDestroyParams](types_composer.md#assetdestroyparams) +- [AssetFreezeParams](types_composer.md#assetfreezeparams) +- [AssetOptInParams](types_composer.md#assetoptinparams) +- [AssetTransferParams](types_composer.md#assettransferparams) +- [CommonTransactionParams](types_composer.md#commontransactionparams) +- [MethodCallParams](types_composer.md#methodcallparams) +- [OnlineKeyRegistrationParams](types_composer.md#onlinekeyregistrationparams) +- [PaymentParams](types_composer.md#paymentparams) + +## Type Aliases + +### AlgokitComposerParams + +Ƭ **AlgokitComposerParams**: `Object` + +Parameters to create an `AlgokitComposer`. + +#### Type declaration + +| Name | Type | Description | +| :------ | :------ | :------ | +| `algod` | `algosdk.Algodv2` | The algod client to use to get suggestedParams and send the transaction group | +| `defaultValidityWindow?` | `number` | How many rounds a transaction should be valid for by default | +| `getSigner` | (`address`: `string`) => `algosdk.TransactionSigner` | - | +| `getSuggestedParams?` | () => `Promise`\<`algosdk.SuggestedParams`\> | - | + +#### Defined in + +[src/types/composer.ts:224](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L224) + +___ + +### AppCallParams + +Ƭ **AppCallParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `accountReferences?`: `string`[] ; `appId?`: `bigint` ; `appReferences?`: `bigint`[] ; `approvalProgram?`: `Uint8Array` ; `args?`: `Uint8Array`[] ; `assetReferences?`: `bigint`[] ; `boxReferences?`: `algosdk.BoxReference`[] ; `clearProgram?`: `Uint8Array` ; `extraPages?`: `number` ; `onComplete?`: `algosdk.OnApplicationComplete` ; `schema?`: \{ `globalByteSlices`: `number` ; `globalUints`: `number` ; `localByteSlices`: `number` ; `localUints`: `number` } } + +Parameters to define an application call transaction. + +#### Defined in + +[src/types/composer.ts:150](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L150) + +___ + +### AssetConfigParams + +Ƭ **AssetConfigParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `assetId`: `bigint` ; `clawback?`: `string` ; `freeze?`: `string` ; `manager?`: `string` ; `reserve?`: `string` } + +Parameters to define an asset config transaction. + +#### Defined in + +[src/types/composer.ts:78](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L78) + +___ + +### AssetCreateParams + +Ƭ **AssetCreateParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `assetName?`: `string` ; `clawback?`: `string` ; `decimals?`: `number` ; `defaultFrozen?`: `boolean` ; `freeze?`: `string` ; `manager?`: `string` ; `metadataHash?`: `Uint8Array` ; `reserve?`: `string` ; `total`: `bigint` ; `unitName?`: `string` ; `url?`: `string` } + +Parameters to define an asset create transaction. + +#### Defined in + +[src/types/composer.ts:52](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L52) + +___ + +### AssetDestroyParams + +Ƭ **AssetDestroyParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `assetId`: `bigint` } + +Parameters to define an asset destroy transaction. + +#### Defined in + +[src/types/composer.ts:102](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L102) + +___ + +### AssetFreezeParams + +Ƭ **AssetFreezeParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `account`: `string` ; `assetId`: `bigint` ; `frozen`: `boolean` } + +Parameters to define an asset freeze transaction. + +#### Defined in + +[src/types/composer.ts:92](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L92) + +___ + +### AssetOptInParams + +Ƭ **AssetOptInParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `assetId`: `bigint` } + +Parameters to define an asset opt-in transaction. + +#### Defined in + +[src/types/composer.ts:122](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L122) + +___ + +### AssetTransferParams + +Ƭ **AssetTransferParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `amount`: `bigint` ; `assetId`: `bigint` ; `clawbackTarget?`: `string` ; `closeAssetTo?`: `string` ; `receiver`: `string` } + +Parameters to define an asset transfer transaction. + +#### Defined in + +[src/types/composer.ts:108](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L108) + +___ + +### CommonTransactionParams + +Ƭ **CommonTransactionParams**: `Object` + +Common parameters for defining a transaction. + +#### Type declaration + +| Name | Type | Description | +| :------ | :------ | :------ | +| `extraFee?` | [`AlgoAmount`](../classes/types_amount.AlgoAmount.md) | The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees | +| `firstValidRound?` | `bigint` | Set the first round this transaction is valid. If left undefined, the value from algod will be used. Only set this when you intentionally want this to be some time in the future | +| `lastValidRound?` | `bigint` | The last round this transaction is valid. It is recommended to use validityWindow instead | +| `lease?` | `Uint8Array` \| `string` | Prevent multiple transactions with the same lease being included within the validity window | +| `maxFee?` | [`AlgoAmount`](../classes/types_amount.AlgoAmount.md) | Throw an error if the fee for the transaction is more than this amount | +| `note?` | `Uint8Array` \| `string` | Note to attach to the transaction | +| `rekeyTo?` | `string` | Change the signing key of the sender to the given address | +| `sender` | `string` | The address sending the transaction | +| `signer?` | `algosdk.TransactionSigner` \| [`TransactionSignerAccount`](../interfaces/types_account.TransactionSignerAccount.md) | The function used to sign transactions | +| `staticFee?` | [`AlgoAmount`](../classes/types_amount.AlgoAmount.md) | The transaction fee. In most cases you want to use `extraFee` unless setting the fee to 0 to be covered by another transaction | +| `validityWindow?` | `number` | How many rounds the transaction should be valid for | + +#### Defined in + +[src/types/composer.ts:12](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L12) + +___ + +### MethodCallParams + +Ƭ **MethodCallParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & `Omit`\<[`AppCallParams`](types_composer.md#appcallparams), ``"args"``\> & \{ `appId`: `bigint` ; `args?`: (`algosdk.ABIValue` \| `TransactionWithSigner` \| `Transaction` \| `Promise`\<`Transaction`\> \| [`MethodCallParams`](types_composer.md#methodcallparams))[] ; `method`: `algosdk.ABIMethod` } + +Parameters to define an ABI method application call transaction. + +#### Defined in + +[src/types/composer.ts:185](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L185) + +___ + +### OnlineKeyRegistrationParams + +Ƭ **OnlineKeyRegistrationParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `selectionKey`: `Uint8Array` ; `stateProofKey?`: `Uint8Array` ; `voteFirst`: `bigint` ; `voteKey`: `Uint8Array` ; `voteKeyDilution`: `bigint` ; `voteLast`: `bigint` } + +Parameters to define an online key registration transaction. + +#### Defined in + +[src/types/composer.ts:128](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L128) + +___ + +### PaymentParams + +Ƭ **PaymentParams**: [`CommonTransactionParams`](types_composer.md#commontransactionparams) & \{ `amount`: [`AlgoAmount`](../classes/types_amount.AlgoAmount.md) ; `closeRemainderTo?`: `string` ; `receiver`: `string` } + +Parameters to define a payment transaction. + +#### Defined in + +[src/types/composer.ts:42](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/composer.ts#L42) diff --git a/docs/code/modules/types_transaction.md b/docs/code/modules/types_transaction.md index ab790463..92c5fdbe 100644 --- a/docs/code/modules/types_transaction.md +++ b/docs/code/modules/types_transaction.md @@ -53,7 +53,7 @@ many types of accounts, including: #### Defined in -[src/types/transaction.ts:100](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L100) +[src/types/transaction.ts:104](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L104) ___ diff --git a/src/account/account.ts b/src/account/account.ts index db7224ce..f7f59fc8 100644 --- a/src/account/account.ts +++ b/src/account/account.ts @@ -3,11 +3,12 @@ import { Config } from '../config' import { getOrCreateKmdWalletAccount } from '../localnet/get-or-create-kmd-wallet-account' import { isLocalNet } from '../localnet/is-localnet' import { getSenderAddress } from '../transaction/transaction' -import { MultisigAccount, SigningAccount, TransactionSignerAccount } from '../types/account' +import { AccountAssetInformation, AccountInformation, MultisigAccount, SigningAccount, TransactionSignerAccount } from '../types/account' import { AlgoAmount } from '../types/amount' import { SendTransactionFrom } from '../types/transaction' import { getAccountConfigFromEnvironment } from './get-account-config-from-environment' import { mnemonicAccount } from './mnemonic-account' +import AccountInformationModel = algosdk.modelsv2.Account import Account = algosdk.Account import Algodv2 = algosdk.Algodv2 import Kmd = algosdk.Kmd @@ -127,3 +128,73 @@ export function getAccountAddressAsUint8Array(account: SendTransactionFrom | str export function getAccountAddressAsString(addressEncodedInB64: string): string { return algosdk.encodeAddress(Buffer.from(addressEncodedInB64, 'base64')) } + +/** + * Returns the given sender account's current status, balance and spendable amounts. + * + * @example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await account.getInformation(address, algod); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddress) + * @param sender The address of the sender/account to look up + * @param algod The algod instance + * @returns The account information + */ +export async function getAccountInformation(sender: string | SendTransactionFrom, algod: Algodv2): Promise { + const account = AccountInformationModel.from_obj_for_encoding( + await algod.accountInformation(typeof sender === 'string' ? sender : getSenderAddress(sender)).do(), + ) + + return { + ...account, + // None of these can practically overflow 2^53 + amount: Number(account.amount), + amountWithoutPendingRewards: Number(account.amountWithoutPendingRewards), + minBalance: Number(account.minBalance), + pendingRewards: Number(account.pendingRewards), + rewards: Number(account.rewards), + round: Number(account.round), + totalAppsOptedIn: Number(account.totalAppsOptedIn), + totalAssetsOptedIn: Number(account.totalAssetsOptedIn), + totalCreatedApps: Number(account.totalCreatedApps), + totalCreatedAssets: Number(account.totalCreatedAssets), + appsTotalExtraPages: account.appsTotalExtraPages ? Number(account.appsTotalExtraPages) : undefined, + rewardBase: account.rewardBase ? Number(account.rewardBase) : undefined, + totalBoxBytes: account.totalBoxBytes ? Number(account.totalBoxBytes) : undefined, + totalBoxes: account.totalBoxes ? Number(account.totalBoxes) : undefined, + } +} + +/** + * Returns the given sender account's asset holding for a given asset. + * + * @example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const assetId = 123345; + * const accountInfo = await account.getAccountAssetInformation(address, assetId, algod); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddressassetsasset-id) + * @param sender The address of the sender/account to look up + * @param assetId The ID of the asset to return a holding for + * @param algod The algod instance + * @returns The account asset holding information + */ +export async function getAccountAssetInformation( + sender: string | SendTransactionFrom, + assetId: number | bigint, + algod: Algodv2, +): Promise { + const info = await algod.accountAssetInformation(typeof sender === 'string' ? sender : getSenderAddress(sender), Number(assetId)).do() + + return { + assetId: BigInt(assetId), + balance: BigInt(info['asset-holding']['amount']), + frozen: info['asset-holding']['is-frozen'] === 'true', + round: BigInt(info['round']), + } +} diff --git a/src/index.ts b/src/index.ts index 8f2c2555..4b530d36 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,3 +12,4 @@ export * from './localnet' export * from './network-client' export * from './transaction' export * from './transfer' +export * from './types/algorand-client' diff --git a/src/indexer-lookup.spec.ts b/src/indexer-lookup.spec.ts index cb464f39..845c822d 100644 --- a/src/indexer-lookup.spec.ts +++ b/src/indexer-lookup.spec.ts @@ -26,7 +26,7 @@ describe('indexer-lookup', () => { expect(txn.transaction.id).toBe(transaction.txID()) expect(txn['current-round']).toBeGreaterThanOrEqual(transaction.firstRound) - }) + }, 20_000) test('Account is found by id', async () => { const { indexer, testAccount, transactionLogger } = localnet.context @@ -35,7 +35,7 @@ describe('indexer-lookup', () => { const account = await algokit.lookupAccountByAddress(testAccount.addr, indexer) expect(account.account.address).toBe(testAccount.addr) - }) + }, 20_000) test('Transactions are searched with pagination', async () => { const { algod, indexer, testAccount, generateAccount, transactionLogger } = localnet.context @@ -62,7 +62,7 @@ describe('indexer-lookup', () => { expect(Number(transactions['current-round'])).toBeGreaterThan(0) expect(transactions.transactions.map((t) => t.id).sort()).toEqual([transaction1.txID(), transaction2.txID()].sort()) - }) + }, 20_000) test('Application create transactions are found by creator with pagination', async () => { const { algod, indexer, testAccount, generateAccount, waitForIndexer } = localnet.context @@ -84,72 +84,5 @@ describe('indexer-lookup', () => { const apps = await algokit.lookupAccountCreatedApplicationByAddress(indexer, testAccount.addr, true, 1) expect(apps.map((a) => a.id).sort()).toEqual([app1.appId, app2.appId].sort()) - }) - - test('Asset transfer and creation transactions are found by search or by ID with amounts gt 53-bit', async () => { - const { algod, indexer, testAccount, generateAccount, waitForIndexer } = localnet.context - const secondAccount = await generateAccount({ - initialFunds: algokit.algos(1), - suppressLog: true, - }) - const asset = await algokit.createAsset( - { - creator: testAccount, - total: 135_640_597_783_270_615n, - decimals: 0, - }, - algod, - ) - await algokit.assetOptIn( - { - account: secondAccount, - assetId: Number(asset.confirmation!.assetIndex), - }, - algod, - ) - const transfer = await algokit.transferAsset( - { - amount: 134_640_597_783_270_615n, - from: testAccount, - to: secondAccount, - assetId: Number(asset.confirmation!.assetIndex), - }, - algod, - ) - const closeOut = await algokit.sendTransaction( - { - transaction: algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({ - assetIndex: Number(asset.confirmation!.assetIndex), - from: algokit.getSenderAddress(secondAccount), - to: algokit.getSenderAddress(testAccount), - closeRemainderTo: algokit.getSenderAddress(testAccount), - amount: 257, - suggestedParams: await algokit.getTransactionParams(undefined, algod), - }), - from: secondAccount, - }, - algod, - ) - await waitForIndexer() - - const searchTransactions = (await algokit.searchTransactions(indexer, (s) => s.assetID(Number(asset.confirmation!.assetIndex)))) - .transactions - - const acfgTxn = await algokit.lookupTransactionById(asset.transaction.txID(), indexer) - const acfgTxnFromSearch = searchTransactions.find((t) => t.id === asset.transaction.txID())! - expect(acfgTxn.transaction['asset-config-transaction']!.params!.total).toBe(135_640_597_783_270_615n) - expect(acfgTxnFromSearch['asset-config-transaction']!.params!.total).toBe(135_640_597_783_270_615n) - - const axferTxn = await algokit.lookupTransactionById(transfer.transaction.txID(), indexer) - const axferTxnFromSearch = searchTransactions.find((t) => t.id === transfer.transaction.txID())! - expect(axferTxn.transaction['asset-transfer-transaction']!.amount).toBe(134_640_597_783_270_615n) - expect(axferTxnFromSearch['asset-transfer-transaction']!.amount).toBe(134_640_597_783_270_615n) - - const closeOutTxn = await algokit.lookupTransactionById(closeOut.transaction.txID(), indexer) - const closeOutTxnFromSearch = searchTransactions.find((t) => t.id === closeOut.transaction.txID())! - expect(closeOutTxn.transaction['asset-transfer-transaction']!.amount).toBe(257) - expect(closeOutTxnFromSearch['asset-transfer-transaction']!.amount).toBe(257) - expect(closeOutTxn.transaction['asset-transfer-transaction']!['close-amount']).toBe(134_640_597_783_270_615n - 257n) - expect(closeOutTxnFromSearch['asset-transfer-transaction']!['close-amount']).toBe(134_640_597_783_270_615n - 257n) - }) + }, 20_000) }) diff --git a/src/testing/fixtures/algorand-fixture.ts b/src/testing/fixtures/algorand-fixture.ts index f235592c..955b6c8c 100644 --- a/src/testing/fixtures/algorand-fixture.ts +++ b/src/testing/fixtures/algorand-fixture.ts @@ -7,6 +7,7 @@ import { getConfigFromEnvOrDefaults, lookupTransactionById, } from '../../' +import AlgorandClient from '../../types/algorand-client' import { AlgoConfig } from '../../types/network-client' import { AlgorandFixture, AlgorandFixtureConfig, AlgorandTestAutomationContext, GetTestAccountParams } from '../../types/testing' import { getTestAccount } from '../account' @@ -92,22 +93,30 @@ export function algorandFixture(fixtureConfig?: AlgorandFixtureConfig, config?: const indexer = fixtureConfig?.indexer ?? getAlgoIndexerClient(config.indexerConfig) const kmd = fixtureConfig?.kmd ?? getAlgoKmdClient(config.kmdConfig) let context: AlgorandTestAutomationContext + let algorandClient: AlgorandClient const beforeEach = async () => { Config.configure({ debug: true }) const transactionLogger = new TransactionLogger() const transactionLoggerAlgod = transactionLogger.capture(algod) + const acc = await getTestAccount( + { initialFunds: fixtureConfig?.testAccountFunding ?? algos(10), suppressLog: true }, + transactionLoggerAlgod, + kmd, + ) + algorandClient = algorandClient ?? AlgorandClient.fromClients({ algod: transactionLoggerAlgod, indexer, kmd }) + algorandClient.setSignerFromAccount(acc).setDefaultValidityWindow(1000).setSuggestedParamsTimeout(0) + const testAccount = { ...acc, signer: algorandClient.account.getSigner(acc.addr) } context = { algod: transactionLoggerAlgod, indexer: indexer, kmd: kmd, - testAccount: await getTestAccount( - { initialFunds: fixtureConfig?.testAccountFunding ?? algos(10), suppressLog: true, accountGetter: fixtureConfig?.accountGetter }, - transactionLoggerAlgod, - kmd, - ), - generateAccount: (params: GetTestAccountParams) => - getTestAccount({ accountGetter: fixtureConfig?.accountGetter, ...params }, transactionLoggerAlgod, kmd), + testAccount, + generateAccount: async (params: GetTestAccountParams) => { + const account = await getTestAccount(params, transactionLoggerAlgod, kmd) + algorandClient.setSignerFromAccount(account) + return { ...account, signer: algorandClient.account.getSigner(account.addr) } + }, transactionLogger: transactionLogger, waitForIndexer: () => transactionLogger.waitForIndexer(indexer), waitForIndexerTransaction: (transactionId: string) => runWhenIndexerCaughtUp(() => lookupTransactionById(transactionId, indexer)), @@ -118,6 +127,9 @@ export function algorandFixture(fixtureConfig?: AlgorandFixtureConfig, config?: get context() { return context }, + get algorand() { + return algorandClient + }, beforeEach, } } diff --git a/src/types/account-manager.ts b/src/types/account-manager.ts new file mode 100644 index 00000000..9e385056 --- /dev/null +++ b/src/types/account-manager.ts @@ -0,0 +1,290 @@ +import algosdk from 'algosdk' +import { + getAccountAssetInformation, + getAccountInformation, + mnemonicAccountFromEnvironment, + multisigAccount, + randomAccount, + rekeyedAccount, +} from '../account/account' +import { getDispenserAccount } from '../account/get-dispenser-account' +import { mnemonicAccount } from '../account/mnemonic-account' +import { getKmdWalletAccount } from '../localnet/get-kmd-wallet-account' +import { getLocalNetDispenserAccount } from '../localnet/get-localnet-dispenser-account' +import { getSenderAddress, getSenderTransactionSigner } from '../transaction/transaction' +import { AccountInformation, SigningAccount, TransactionSignerAccount } from './account' +import { AlgoAmount } from './amount' +import { ClientManager } from './client-manager' +import { SendTransactionFrom } from './transaction' +import LogicSigAccount = algosdk.LogicSigAccount + +/** Creates and keeps track of signing accounts that can sign transactions for a sending address. */ +export class AccountManager { + private _clientManager: ClientManager + private _accounts: { [address: string]: TransactionSignerAccount } = {} + private _defaultSigner?: algosdk.TransactionSigner + + /** + * Create a new account manager. + * @param clientManager The ClientManager client to use for algod and kmd clients + */ + constructor(clientManager: ClientManager) { + this._clientManager = clientManager + } + + /** + * Sets the default signer to use if no other signer is specified. + * + * If this isn't set an a transaction needs signing for a given sender + * then an error will be thrown from `getSigner` / `getAccount`. + * @param signer The signer to use, either a `TransactionSigner` or a `TransactionSignerAccount` + * @returns The `AccountManager` so method calls can be chained + */ + public setDefaultSigner(signer: algosdk.TransactionSigner | TransactionSignerAccount): AccountManager { + this._defaultSigner = 'signer' in signer ? signer.signer : signer + return this + } + + /** + * Records the given account against the address of the account for later + * retrieval and returns a `TransactionSignerAccount`. + */ + private signerAccount(account: T): TransactionSignerAccount & { account: T } { + const acc = { + addr: getSenderAddress(account), + signer: getSenderTransactionSigner(account), + } + this._accounts[acc.addr] = acc + return { ...acc, account } + } + + /** + * Tracks the given account for later signing. + * @param account The account to register, which can be a `TransactionSignerAccount` + * or any `SendTransactionFrom` compatible account object + * @returns The `AccountManager` instance for method chaining + */ + public setSignerFromAccount(account: TransactionSignerAccount | SendTransactionFrom) { + this.signerAccount(account) + return this + } + + /** + * Tracks the given account for later signing. + * @param sender The sender address to use this signer for + * @param signer The signer to sign transactions with for the given sender + * @returns The `AccountManager` instance for method chaining + */ + public setSigner(sender: string, signer: algosdk.TransactionSigner) { + this._accounts[sender] = { addr: sender, signer } + return this + } + + /** + * Returns the `TransactionSigner` for the given sender address. + * + * If no signer has been registered for that address then the default signer is used if registered. + * + * @param sender The sender address + * @returns The `TransactionSigner` or throws an error if not found + */ + public getSigner(sender: string): algosdk.TransactionSigner { + const signer = this._accounts[sender]?.signer ?? this._defaultSigner + if (!signer) throw new Error(`No signer found for address ${sender}`) + return signer + } + + /** + * Returns the `TransactionSignerAccount` for the given sender address. + * @param sender The sender address + * @returns The `TransactionSignerAccount` or throws an error if not found + */ + public getAccount(sender: string): TransactionSignerAccount { + const account = this._accounts[sender] + if (!account) throw new Error(`No signer found for address ${sender}`) + return account + } + + /** + * Returns the given sender account's current status, balance and spendable amounts. + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddress) + * @example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await accountManager.getInformation(address); + * ``` + * + * @param sender The account / address to look up + * @returns The account information + */ + public async getInformation(sender: string | TransactionSignerAccount): Promise { + return getAccountInformation(sender, this._clientManager.algod) + } + + /** + * Returns the given sender account's asset holding for a given asset. + * + * @example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const assetId = 123345; + * const accountInfo = await accountManager.getAccountAssetInformation(address, assetId); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/#get-v2accountsaddressassetsasset-id) + * @param sender The address of the sender/account to look up + * @param assetId The ID of the asset to return a holding for + * @returns The account asset holding information + */ + public async getAssetInformation(sender: string | TransactionSignerAccount, assetId: number | bigint) { + return getAccountAssetInformation(sender, assetId, this._clientManager.algod) + } + + /** + * Tracks and returns an Algorand account with secret key loaded (i.e. that can sign transactions) by taking the mnemonic secret. + * + * @example + * ```typescript + * const account = await account.fromMnemonic("mnemonic secret ...") + * const rekeyedAccount = await account.fromMnemonic("mnemonic secret ...", "SENDERADDRESS...") + * ``` + * @param mnemonicSecret The mnemonic secret representing the private key of an account; **Note: Be careful how the mnemonic is handled**, + * never commit it into source control and ideally load it from the environment (ideally via a secret storage service) rather than the file system. + * @param sender The optional sender address to use this signer for (aka a rekeyed account) + * @returns The account + */ + public fromMnemonic(mnemonicSecret: string, sender?: string) { + const account = mnemonicAccount(mnemonicSecret) + return this.signerAccount(sender ? rekeyedAccount(account, sender) : account) + } + + /** + * Tracks and returns an Algorand account with private key loaded by convention from environment variables based on the given name identifier. + * + * Note: This function expects to run in a Node.js environment. + * + * ## Convention: + * * **Non-LocalNet:** will load process.env['\{NAME\}_MNEMONIC'] as a mnemonic secret; **Note: Be careful how the mnemonic is handled**, + * never commit it into source control and ideally load it via a secret storage service rather than the file system. + * If process.env['\{NAME\}_SENDER'] is defined then it will use that for the sender address (i.e. to support rekeyed accounts) + * * **LocalNet:** will load the account from a KMD wallet called \{NAME\} and if that wallet doesn't exist it will create it and fund the account for you + * + * This allows you to write code that will work seamlessly in production and local development (LocalNet) without manual config locally (including when you reset the LocalNet). + * + * @example Default + * + * If you have a mnemonic secret loaded into `process.env.MY_ACCOUNT_MNEMONIC` then you can call the following to get that private key loaded into an account object: + * ```typescript + * const account = await account.fromEnvironment('MY_ACCOUNT', algod) + * ``` + * + * If that code runs against LocalNet then a wallet called `MY_ACCOUNT` will automatically be created with an account that is automatically funded with 1000 (default) ALGOs from the default LocalNet dispenser. + * If not running against LocalNet then it will use proces.env.MY_ACCOUNT_MNEMONIC as the private key and (if present) process.env.MY_ACCOUNT_SENDER as the sender address. + * + * @param name The name identifier of the account + * @param fundWith The optional amount to fund the account with when it gets created (when targeting LocalNet), if not specified then 1000 Algos will be funded from the dispenser account + * @returns The account + */ + public async fromEnvironment(name: string, fundWith?: AlgoAmount) { + this.signerAccount(await mnemonicAccountFromEnvironment({ name, fundWith }, this._clientManager.algod, this._clientManager.kmd)) + } + + /** + * Tracks and returns an Algorand account with private key loaded from the given KMD wallet (identified by name). + * + * @param name The name of the wallet to retrieve an account from + * @param predicate An optional filter to use to find the account (otherwise it will return a random account from the wallet) + * @param sender The optional sender address to use this signer for (aka a rekeyed account) + * @example Get default funded account in a LocalNet + * + * ```typescript + * const defaultDispenserAccount = await account.fromKmd('unencrypted-default-wallet', + * a => a.status !== 'Offline' && a.amount > 1_000_000_000 + * ) + * ``` + * @returns The account + */ + public async fromKmd( + name: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + predicate?: (account: Record) => boolean, + sender?: string, + ) { + const account = await getKmdWalletAccount({ name, predicate }, this._clientManager.algod, this._clientManager.kmd) + if (!account) throw new Error(`Unable to find KMD account ${name}${predicate ? ' with predicate' : ''}`) + return this.signerAccount(sender ? rekeyedAccount(account, sender) : account) + } + + /** + * Tracks and returns an account that supports partial or full multisig signing. + * + * @example + * ```typescript + * const account = await account.multisig({version: 1, threshold: 1, addrs: ["ADDRESS1...", "ADDRESS2..."]}, + * await account.fromEnvironment('ACCOUNT1')) + * ``` + * @param multisigParams The parameters that define the multisig account + * @param signingAccounts The signers that are currently present + * @returns A multisig account wrapper + */ + public multisig(multisigParams: algosdk.MultisigMetadata, signingAccounts: (algosdk.Account | SigningAccount)[]) { + return this.signerAccount(multisigAccount(multisigParams, signingAccounts)) + } + + /** + * Tracks and returns an account that represents a logic signature. + * + * @example + * ```typescript + * const account = await account.logicsig(program, [new Uint8Array(3, ...)]) + * ``` + * @param program The bytes that make up the compiled logic signature + * @param args The (binary) arguments to pass into the logic signature + * @returns A logic signature account wrapper + */ + public logicsig(program: Uint8Array, args?: Array) { + this.signerAccount(new LogicSigAccount(program, args)) + } + + /** + * Tracks and returns a new, random Algorand account with secret key loaded. + * + * @example + * ```typescript + * const account = await account.random() + * ``` + * @returns The account + */ + public random() { + this.signerAccount(randomAccount()) + } + + /** + * Returns an account (with private key loaded) that can act as a dispenser. + * + * @example + * ```typescript + * const account = await account.dispenser() + * ``` + * If running on LocalNet then it will return the default dispenser account automatically, + * otherwise it will load the account mnemonic stored in process.env.DISPENSER_MNEMONIC. + * @returns The account + */ + public async dispenser() { + this.signerAccount(await getDispenserAccount(this._clientManager.algod, this._clientManager.kmd)) + } + + /** + * Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts). + * + * @example + * ```typescript + * const account = await account.localNetDispenser() + * ``` + * @returns The account + */ + public async localNetDispenser() { + this.signerAccount(await getLocalNetDispenserAccount(this._clientManager.algod, this._clientManager.kmd)) + } +} diff --git a/src/types/account.ts b/src/types/account.ts index ee102cf4..0dcf2c70 100644 --- a/src/types/account.ts +++ b/src/types/account.ts @@ -1,4 +1,5 @@ import algosdk from 'algosdk' +import AccountInformationModel = algosdk.modelsv2.Account import Account = algosdk.Account import MultisigMetadata = algosdk.MultisigMetadata import Transaction = algosdk.Transaction @@ -126,3 +127,20 @@ export interface AccountConfig { /** @deprecated Renamed to senderAddress in 2.3.1 */ senderMnemonic?: string } + +type NumberConverter = { [key in keyof T]: ToNumberIfExtends } +type ToNumberIfExtends = K extends E ? number : K +/** Account information at a given round. */ +export type AccountInformation = Omit, 'get_obj_for_encoding'> + +/** Account asset holding information at a given round. */ +export type AccountAssetInformation = { + /** The ID of the asset held. */ + assetId: bigint + /** The current balance of that asset holding. */ + balance: bigint + /** Whether or not the asset is frozen for the account. */ + frozen: boolean + /** The round as at which the holding was correct. */ + round: bigint +} diff --git a/src/types/algorand-client.spec.ts b/src/types/algorand-client.spec.ts new file mode 100644 index 00000000..05ed62e3 --- /dev/null +++ b/src/types/algorand-client.spec.ts @@ -0,0 +1,199 @@ +/* eslint-disable no-console */ +import { TestContractClient } from '../../tests/example-contracts/client/TestContractClient' +import * as algokit from '../index' +import { algorandFixture } from '../testing' +import { TransactionSignerAccount } from './account' +import AlgorandClient from './algorand-client' +import { MethodCallParams } from './composer' + +describe('AlgorandClient', () => { + let algorand: AlgorandClient + let alice: TransactionSignerAccount + let bob: TransactionSignerAccount + let appClient: TestContractClient + let appId: bigint + + const fixture = algorandFixture() + + beforeAll(async () => { + await fixture.beforeEach() + + alice = fixture.context.testAccount + bob = await fixture.context.generateAccount({ initialFunds: algokit.microAlgos(100_000) }) + + algorand = fixture.algorand + appClient = algorand.client.getTypedAppClientById(TestContractClient, { + id: 0, + sender: alice, + }) + + const app = await appClient.create.createApplication({}) + appId = BigInt(app.appId) + }, 10_000) + + test('sendPayment', async () => { + const alicePreBalance = (await algorand.account.getInformation(alice)).amount + const bobPreBalance = (await algorand.account.getInformation(bob)).amount + await algorand.send.payment({ sender: alice.addr, receiver: bob.addr, amount: algokit.microAlgos(1) }) + const alicePostBalance = (await algorand.account.getInformation(alice)).amount + const bobPostBalance = (await algorand.account.getInformation(bob)).amount + + expect(alicePostBalance).toBe(alicePreBalance - 1001) + expect(bobPostBalance).toBe(bobPreBalance + 1) + }) + + test('sendAssetCreate', async () => { + const createResult = await algorand.send.assetCreate({ sender: alice.addr, total: 100n }) + + const assetIndex = Number(createResult.confirmation.assetIndex) + + expect(assetIndex).toBeGreaterThan(0) + }) + + test('addAtc from generated client', async () => { + const alicePreBalance = (await algorand.account.getInformation(alice)).amount + const bobPreBalance = (await algorand.account.getInformation(bob)).amount + + const doMathAtc = await appClient.compose().doMath({ a: 1, b: 2, operation: 'sum' }).atc() + const result = await algorand + .newGroup() + .addPayment({ sender: alice.addr, receiver: bob.addr, amount: algokit.microAlgos(1) }) + .addAtc(doMathAtc) + .execute() + + const alicePostBalance = (await algorand.account.getInformation(alice)).amount + const bobPostBalance = (await algorand.account.getInformation(bob)).amount + + expect(alicePostBalance).toBe(alicePreBalance - 2001) + expect(bobPostBalance).toBe(bobPreBalance + 1) + + expect(result.returns?.[0].returnValue?.valueOf()).toBe(3n) + }) + + test('addMethodCall', async () => { + const alicePreBalance = (await algorand.account.getInformation(alice)).amount + const bobPreBalance = (await algorand.account.getInformation(bob)).amount + + const methodRes = await algorand + .newGroup() + .addPayment({ sender: alice.addr, receiver: bob.addr, amount: algokit.microAlgos(1), note: new Uint8Array([1]) }) + .addMethodCall({ + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('doMath')!, + args: [1, 2, 'sum'], + }) + .execute() + + const alicePostBalance = (await algorand.account.getInformation(alice)).amount + const bobPostBalance = (await algorand.account.getInformation(bob)).amount + + expect(alicePostBalance).toBe(alicePreBalance - 2001) + expect(bobPostBalance).toBe(bobPreBalance + 1) + + expect(methodRes.returns?.[0].returnValue?.valueOf()).toBe(3n) + }) + + test('method with txn arg', async () => { + const txnArgParams = { + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('txnArg')!, + args: [algorand.transactions.payment({ sender: alice.addr, receiver: alice.addr, amount: algokit.microAlgos(0) })], + } + + const txnRes = await algorand + .newGroup() + .addPayment({ sender: alice.addr, receiver: alice.addr, amount: algokit.microAlgos(0), note: new Uint8Array([1]) }) + .addMethodCall(txnArgParams) + .execute() + + expect(txnRes.returns?.[0].returnValue?.valueOf()).toBe(alice.addr) + }) + + test('method with method call arg', async () => { + const helloWorldCall = { + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('helloWorld')!, + } satisfies MethodCallParams + + const methodArgRes = await algorand + .newGroup() + .addMethodCall({ + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('methodArg')!, + args: [helloWorldCall], + }) + .execute() + + expect(methodArgRes.returns?.[0].returnValue?.valueOf()).toBe('Hello, World!') + expect(methodArgRes.returns?.[1].returnValue?.valueOf()).toBe(BigInt(appId)) + }) + + test('method with method call arg that has a txn arg', async () => { + const txnArgCall = { + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('txnArg')!, + args: [algorand.transactions.payment({ sender: alice.addr, receiver: alice.addr, amount: algokit.microAlgos(0) })], + } satisfies MethodCallParams + + const nestedTxnArgRes = await algorand + .newGroup() + .addMethodCall({ + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('nestedTxnArg')!, + args: [txnArgCall], + }) + .execute() + + expect(nestedTxnArgRes.returns?.[0].returnValue?.valueOf()).toBe(alice.addr) + expect(nestedTxnArgRes.returns?.[1].returnValue?.valueOf()).toBe(BigInt(appId)) + }) + + test('method with two method call args that each have a txn arg', async () => { + const firstTxnCall = { + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('txnArg')!, + args: [algorand.transactions.payment({ sender: alice.addr, receiver: alice.addr, amount: algokit.microAlgos(0) })], + } satisfies MethodCallParams + + const secondTxnCall = { + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('txnArg')!, + args: [algorand.transactions.payment({ sender: alice.addr, receiver: alice.addr, amount: algokit.microAlgos(1) })], + note: new Uint8Array([1]), + } satisfies MethodCallParams + + const doubleNestedTxnArgRes = await algorand + .newGroup() + .addMethodCall({ + sender: alice.addr, + appId: appId, + method: appClient.appClient.getABIMethod('doubleNestedTxnArg')!, + args: [firstTxnCall, secondTxnCall], + }) + .execute() + + expect(doubleNestedTxnArgRes.returns?.[0].returnValue?.valueOf()).toBe(alice.addr) + expect(doubleNestedTxnArgRes.returns?.[1].returnValue?.valueOf()).toBe(alice.addr) + expect(doubleNestedTxnArgRes.returns?.[2].returnValue?.valueOf()).toBe(BigInt(appId)) + }) + + test('assetOptIn', async () => { + const { algod } = fixture.context + const assetId = BigInt((await algorand.send.assetCreate({ sender: alice.addr, total: 1n })).confirmation.assetIndex!) + + await algorand.send.assetOptIn({ + sender: alice.addr, + assetId: assetId, + signer: alice, + }) + expect(await algod.accountAssetInformation(alice.addr, Number(assetId)).do()).toBeDefined() + }) +}) diff --git a/src/types/algorand-client.ts b/src/types/algorand-client.ts new file mode 100644 index 00000000..529fba49 --- /dev/null +++ b/src/types/algorand-client.ts @@ -0,0 +1,343 @@ +import algosdk from 'algosdk' +import { Config } from '../config' +import { getAlgoNodeConfig, getConfigFromEnvOrDefaults, getDefaultLocalNetConfig } from '../network-client' +import { TransactionSignerAccount } from './account' +import { AccountManager } from './account-manager' +import { AlgoSdkClients, ClientManager } from './client-manager' +import AlgokitComposer, { ExecuteParams, MethodCallParams } from './composer' +import { AlgoConfig } from './network-client' +import { ConfirmedTransactionResult, SendAtomicTransactionComposerResults, SendTransactionFrom } from './transaction' +import Transaction = algosdk.Transaction + +/** Result from sending a single transaction. */ +export type SendSingleTransactionResult = SendAtomicTransactionComposerResults & ConfirmedTransactionResult + +/** A client that brokers easy access to Algorand functionality. + * + * Note: this class is a new Beta feature and may be subject to change. + * + * @beta + */ +export class AlgorandClient { + private _clientManager: ClientManager + private _accountManager: AccountManager + + private _cachedSuggestedParams?: algosdk.SuggestedParams + private _cachedSuggestedParamsExpiry?: Date + private _cachedSuggestedParamsTimeout: number = 3_000 // three seconds + + private _defaultValidityWindow: number = 10 + + private constructor(config: AlgoConfig | AlgoSdkClients) { + this._clientManager = new ClientManager(config) + this._accountManager = new AccountManager(this._clientManager) + } + + /** + * Sets the default validity window for transactions. + * @param validityWindow The number of rounds between the first and last valid rounds + * @returns The `AlgorandClient` so method calls can be chained + */ + public setDefaultValidityWindow(validityWindow: number) { + this._defaultValidityWindow = validityWindow + return this + } + + /** + * Sets the default signer to use if no other signer is specified. + * @param signer The signer to use, either a `TransactionSigner` or a `TransactionSignerAccount` + * @returns The `AlgorandClient` so method calls can be chained + */ + public setDefaultSigner(signer: algosdk.TransactionSigner | TransactionSignerAccount): AlgorandClient { + this._accountManager.setDefaultSigner(signer) + return this + } + + /** + * Tracks the given account for later signing. + * @param account The account to register + * @returns The `AlgorandClient` so method calls can be chained + */ + public setSignerFromAccount(account: TransactionSignerAccount | SendTransactionFrom) { + this._accountManager.setSignerFromAccount(account) + return this + } + + /** + * Tracks the given account for later signing. + * @param sender The sender address to use this signer for + * @param signer The signer to sign transactions with for the given sender + * @returns The `AlgorandClient` so method calls can be chained + */ + public setSigner(sender: string, signer: algosdk.TransactionSigner) { + this._accountManager.setSigner(sender, signer) + return this + } + + /** + * Sets a cache value to use for suggested params. + * @param suggestedParams The suggested params to use + * @param until A date until which to cache, or if not specified then the timeout is used + * @returns The `AlgorandClient` so method calls can be chained + */ + public setSuggestedParams(suggestedParams: algosdk.SuggestedParams, until?: Date) { + this._cachedSuggestedParams = suggestedParams + this._cachedSuggestedParamsExpiry = until ?? new Date(+new Date() + this._cachedSuggestedParamsTimeout) + return this + } + + /** + * Sets the timeout for caching suggested params. + * @param timeout The timeout in milliseconds + * @returns The `AlgorandClient` so method calls can be chained + */ + public setSuggestedParamsTimeout(timeout: number) { + this._cachedSuggestedParamsTimeout = timeout + return this + } + + /** Get suggested params for a transaction (either cached or from algod if the cache is stale or empty) */ + async getSuggestedParams(): Promise { + if (this._cachedSuggestedParams && (!this._cachedSuggestedParamsExpiry || this._cachedSuggestedParamsExpiry > new Date())) { + return { + ...this._cachedSuggestedParams, + } + } + + this._cachedSuggestedParams = await this._clientManager.algod.getTransactionParams().do() + this._cachedSuggestedParamsExpiry = new Date(new Date().getTime() + this._cachedSuggestedParamsTimeout) + + return { + ...this._cachedSuggestedParams, + } + } + + /** Get clients, including algosdk clients and app clients. */ + public get client() { + return this._clientManager + } + + /** Get or create accounts that can sign transactions. */ + public get account() { + return this._accountManager + } + + /** Start a new `AlgokitComposer` transaction group */ + newGroup() { + return new AlgokitComposer({ + algod: this.client.algod, + getSigner: (addr: string) => this.account.getSigner(addr), + getSuggestedParams: () => this.getSuggestedParams(), + defaultValidityWindow: this._defaultValidityWindow, + }) + } + + private _send( + c: (c: AlgokitComposer) => (params: T) => AlgokitComposer, + log?: { + preLog?: (params: T, transaction: Transaction) => string + postLog?: (params: T, result: SendSingleTransactionResult) => string + }, + ): (params: T, config?: ExecuteParams) => Promise { + return async (params, config) => { + const composer = this.newGroup() + + // Ensure `this` is properly populated + c(composer).apply(composer, [params]) + + if (log?.preLog) { + const transaction = (await composer.build()).transactions.at(-1)!.txn + Config.getLogger(config?.suppressLog).debug(log.preLog(params, transaction)) + } + + const rawResult = await composer.execute(config) + const result = { + // Last item covers when a group is created by an app call with ABI transaction parameters + transaction: rawResult.transactions[rawResult.transactions.length - 1], + confirmation: rawResult.confirmations![rawResult.confirmations!.length - 1], + txId: rawResult.txIds[0], + ...rawResult, + } + + if (log?.postLog) { + Config.getLogger(config?.suppressLog).debug(log.postLog(params, result)) + } + + return result + } + } + + /** + * Methods for sending a single transaction. + */ + send = { + /** + * Send a payment transaction. + */ + payment: this._send((c) => c.addPayment, { + preLog: (params, transaction) => + `Sending ${params.amount.microAlgos} µALGOs from ${params.sender} to ${params.receiver} via transaction ${transaction.txID()}`, + }), + /** + * Create an asset. + */ + assetCreate: this._send((c) => c.addAssetCreate, { + postLog: (params, result) => + `Created asset${params.assetName ? ` ${params.assetName} ` : ''}${params.unitName ? ` (${params.unitName}) ` : ''} with ${params.total} units and ${params.decimals ?? 0} decimals created by ${params.sender} with ID ${result.confirmation.assetIndex} via transaction ${result.txIds.at(-1)}`, + }), + /** + * Configure an existing asset. + */ + assetConfig: this._send((c) => c.addAssetConfig, { + preLog: (params, transaction) => `Configuring asset with ID ${params.assetId} via transaction ${transaction.txID()}`, + }), + /** + * Freeze or unfreeze an asset. + */ + assetFreeze: this._send((c) => c.addAssetFreeze, { + preLog: (params, transaction) => `Freezing asset with ID ${params.assetId} via transaction ${transaction.txID()}`, + }), + /** + * Destroy an asset. + */ + assetDestroy: this._send((c) => c.addAssetDestroy, { + preLog: (params, transaction) => `Destroying asset with ID ${params.assetId} via transaction ${transaction.txID()}`, + }), + /** + * Transfer an asset. + */ + assetTransfer: this._send((c) => c.addAssetTransfer, { + preLog: (params, transaction) => + `Transferring ${params.amount} units of asset with ID ${params.assetId} from ${params.sender} to ${params.receiver} via transaction ${transaction.txID()}`, + }), + /** + * Opt an account into an asset. + */ + assetOptIn: this._send((c) => c.addAssetOptIn, { + preLog: (params, transaction) => + `Opting in ${params.sender} to asset with ID ${params.assetId} via transaction ${transaction.txID()}`, + }), + /** + * Call a smart contract. + * + * Note: you may prefer to use `algorandClient.client` to get an app client for more advanced functionality. + */ + appCall: this._send((c) => c.addAppCall), + /** + * Call a smart contract ABI method. + * + * Note: you may prefer to use `algorandClient.client` to get an app client for more advanced functionality. + */ + methodCall: this._send((c) => c.addMethodCall), + /** Register an online key. */ + onlineKeyRegistration: this._send((c) => c.addOnlineKeyRegistration, { + preLog: (params, transaction) => `Registering online key for ${params.sender} via transaction ${transaction.txID()}`, + }), + } + + private _transaction(c: (c: AlgokitComposer) => (params: T) => AlgokitComposer): (params: T) => Promise { + return async (params: T) => { + const composer = this.newGroup() + const result = await c(composer).apply(composer, [params]).build() + return result.transactions.map((ts) => ts.txn)[0] + } + } + + /** + * Methods for building transactions + */ + transactions = { + /** Create a payment transaction. */ + payment: this._transaction((c) => c.addPayment), + /** Create an asset creation transaction. */ + assetCreate: this._transaction((c) => c.addAssetCreate), + /** Create an asset config transaction. */ + assetConfig: this._transaction((c) => c.addAssetConfig), + /** Create an asset freeze transaction. */ + assetFreeze: this._transaction((c) => c.addAssetFreeze), + /** Create an asset destroy transaction. */ + assetDestroy: this._transaction((c) => c.addAssetDestroy), + /** Create an asset transfer transaction. */ + assetTransfer: this._transaction((c) => c.addAssetTransfer), + /** Create an asset opt-in transaction. */ + assetOptIn: this._transaction((c) => c.addAssetOptIn), + /** Create an application call transaction. */ + appCall: this._transaction((c) => c.addAppCall), + /** Create an application call with ABI method call transaction. */ + methodCall: async (params: MethodCallParams) => { + return (await this.newGroup().addMethodCall(params).build()).transactions.map((ts) => ts.txn) + }, + /** Create an online key registration transaction. */ + onlineKeyRegistration: this._transaction((c) => c.addOnlineKeyRegistration), + } + + // Static methods to create an `AlgorandClient` + + /** + * Returns an `AlgorandClient` pointing at default LocalNet ports and API token. + * @returns The `AlgorandClient` + */ + public static defaultLocalNet() { + return new AlgorandClient({ + algodConfig: getDefaultLocalNetConfig('algod'), + indexerConfig: getDefaultLocalNetConfig('indexer'), + kmdConfig: getDefaultLocalNetConfig('kmd'), + }) + } + + /** + * Returns an `AlgorandClient` pointing at TestNet using AlgoNode. + * @returns The `AlgorandClient` + */ + public static testNet() { + return new AlgorandClient({ + algodConfig: getAlgoNodeConfig('testnet', 'algod'), + indexerConfig: getAlgoNodeConfig('testnet', 'indexer'), + kmdConfig: undefined, + }) + } + + /** + * Returns an `AlgorandClient` pointing at MainNet using AlgoNode. + * @returns The `AlgorandClient` + */ + public static mainNet() { + return new AlgorandClient({ + algodConfig: getAlgoNodeConfig('mainnet', 'algod'), + indexerConfig: getAlgoNodeConfig('mainnet', 'indexer'), + kmdConfig: undefined, + }) + } + + /** + * Returns an `AlgorandClient` pointing to the given client(s). + * @param clients The clients to use + * @returns The `AlgorandClient` + */ + public static fromClients(clients: AlgoSdkClients) { + return new AlgorandClient(clients) + } + + /** + * Returns an `AlgorandClient` loading the configuration from environment variables. + * + * Retrieve configurations from environment variables when defined or get defaults. + * + * Expects to be called from a Node.js environment. + * @returns The `AlgorandClient` + */ + public static fromEnvironment() { + return new AlgorandClient(getConfigFromEnvOrDefaults()) + } + + /** + * Returns an `AlgorandClient` from the given config. + * @param config The config to use + * @returns The `AlgorandClient` + */ + public static fromConfig(config: AlgoConfig) { + return new AlgorandClient(config) + } +} + +export default AlgorandClient diff --git a/src/types/client-manager.ts b/src/types/client-manager.ts new file mode 100644 index 00000000..c776f7d3 --- /dev/null +++ b/src/types/client-manager.ts @@ -0,0 +1,162 @@ +import algosdk from 'algosdk' +import { getTestNetDispenserApiClient } from '../dispenser-client' +import { getAlgoClient, getAlgoIndexerClient, getAlgoKmdClient } from '../network-client' +import { AppLookup } from './app' +import { + AppDetails, + AppDetailsBase, + AppSpecAppDetailsBase, + ApplicationClient, + ResolveAppByCreatorAndNameBase, + ResolveAppByIdBase, +} from './app-client' +import { TestNetDispenserApiClientParams } from './dispenser-client' +import { AlgoConfig } from './network-client' + +/** Clients from algosdk that interact with the official Algorand APIs */ +export interface AlgoSdkClients { + /** Algod client, see https://developer.algorand.org/docs/rest-apis/algod/ */ + algod: algosdk.Algodv2 + /** Optional indexer client, see https://developer.algorand.org/docs/rest-apis/indexer/ */ + indexer?: algosdk.Indexer + /** Optional KMD client, see https://developer.algorand.org/docs/rest-apis/kmd/ */ + kmd?: algosdk.Kmd +} + +/** Exposes access to various API clients. */ +export class ClientManager { + private _algod: algosdk.Algodv2 + private _indexer?: algosdk.Indexer + private _kmd?: algosdk.Kmd + + /** + * algosdk clients or config for interacting with the official Algorand APIs. + * @param clientsOrConfig The clients or config to use + */ + constructor(clientsOrConfig: AlgoConfig | AlgoSdkClients) { + const _clients = + 'algod' in clientsOrConfig + ? clientsOrConfig + : { + algod: getAlgoClient(clientsOrConfig.algodConfig), + indexer: clientsOrConfig.indexerConfig ? getAlgoIndexerClient(clientsOrConfig.indexerConfig) : undefined, + kmd: clientsOrConfig.kmdConfig ? getAlgoKmdClient(clientsOrConfig.kmdConfig) : undefined, + } + this._algod = _clients.algod + this._indexer = _clients.indexer + this._kmd = _clients.kmd + } + + /** Returns an algosdk Algod API client. */ + public get algod(): algosdk.Algodv2 { + return this._algod + } + + /** Returns an algosdk Indexer API client or throws an error if it's not been provided. */ + public get indexer(): algosdk.Indexer { + if (!this._indexer) throw new Error('Attempt to use Indexer client in AlgoKit instance with no Indexer configured') + return this._indexer + } + + /** Returns an algosdk KMD API client or throws an error if it's not been provided. */ + public get kmd(): algosdk.Kmd { + if (!this._kmd) throw new Error('Attempt to use Kmd client in AlgoKit instance with no Kmd configured') + return this._kmd + } + + /** + * Returns a TestNet Dispenser API client. + * Refer to [docs](https://github.com/algorandfoundation/algokit/blob/main/docs/testnet_api.md) on guidance to obtain an access token. + * + * @param params An object containing parameters for the TestNetDispenserApiClient class. + * Or null if you want the client to load the access token from the environment variable `ALGOKIT_DISPENSER_ACCESS_TOKEN`. + * @example + * const client = algokit.getTestNetDispenserApiClient( + * { + * authToken: 'your_auth_token', + * requestTimeout: 15, + * } + * ) + * + * @returns An instance of the TestNetDispenserApiClient class. + */ + public getTestNetDispenser(params: TestNetDispenserApiClientParams | null = null) { + return getTestNetDispenserApiClient(params) + } + + /** + * Returns a new `ApplicationClient` client, resolving the app by creator address and name. + * @param details The details to resolve the app by creator address and name + * @param cachedAppLookup A cached app lookup that matches a name to on-chain details; either this is needed or indexer is required to be passed in to this manager on construction. + * @returns The `ApplicationClient` + */ + public getAppClientByCreatorAndName(details: AppClientByCreatorAndNameDetails, cachedAppLookup?: AppLookup) { + return new ApplicationClient( + { ...details, resolveBy: 'creatorAndName', findExistingUsing: cachedAppLookup ?? this.indexer }, + this._algod, + ) + } + + /** + * Returns a new `ApplicationClient` client, resolving the app by app ID. + * @param details The details to resolve the app by ID + * @returns The `ApplicationClient` + */ + public getAppClientById(details: AppClientByIdDetails) { + return new ApplicationClient({ ...details, resolveBy: 'id' }, this._algod) + } + + /** + * Returns a new typed client, resolving the app by creator address and name. + * @param typedClient The typed client type to use + * @param details The details to resolve the app by creator address and name + * @param cachedAppLookup A cached app lookup that matches a name to on-chain details; either this is needed or indexer is required to be passed in to this manager on construction. + * @returns The typed client instance + */ + public getTypedAppClientByCreatorAndName( + typedClient: TypedAppClient, + details: TypedAppClientByCreatorAndNameDetails, + cachedAppLookup?: AppLookup, + ) { + return new typedClient({ ...details, resolveBy: 'creatorAndName', findExistingUsing: cachedAppLookup ?? this.indexer }, this._algod) + } + + /** + * Returns a new typed client, resolving the app by app ID. + * @param typedClient The typed client type to use + * @param details The details to resolve the app by ID + * @returns The typed client instance + */ + public getTypedAppClientById(typedClient: TypedAppClient, details: TypedAppClientByIdDetails) { + return new typedClient({ ...details, resolveBy: 'id' }, this._algod) + } +} + +/** + * Interface to identify a typed client that can be used to interact with an application. + */ +export interface TypedAppClient { + new (details: AppDetails, algod: algosdk.Algodv2): TClient +} + +/** + * Details to resolve an app client by creator address and name. + */ +export type AppClientByCreatorAndNameDetails = AppSpecAppDetailsBase & + AppDetailsBase & + Omit + +/** + * Details to resolve a typed app creator address and name. + */ +export type TypedAppClientByCreatorAndNameDetails = AppDetailsBase & Omit + +/** + * Details to resolve an app client by app ID. + */ +export type AppClientByIdDetails = AppSpecAppDetailsBase & AppDetailsBase & ResolveAppByIdBase + +/** + * Details to resolve a typed app by app ID. + */ +export type TypedAppClientByIdDetails = AppDetailsBase & ResolveAppByIdBase diff --git a/src/types/composer.ts b/src/types/composer.ts new file mode 100644 index 00000000..2d927e6b --- /dev/null +++ b/src/types/composer.ts @@ -0,0 +1,771 @@ +import algosdk from 'algosdk' +import { encodeLease, encodeTransactionNote, sendAtomicTransactionComposer } from '../transaction/transaction' +import { TransactionSignerAccount } from './account' +import { AlgoAmount } from './amount' +import { SendAtomicTransactionComposerResults } from './transaction' +import Transaction = algosdk.Transaction +import TransactionWithSigner = algosdk.TransactionWithSigner +import isTransactionWithSigner = algosdk.isTransactionWithSigner +import encodeAddress = algosdk.encodeAddress + +/** Common parameters for defining a transaction. */ +export type CommonTransactionParams = { + /** The address sending the transaction */ + sender: string + /** The function used to sign transactions */ + signer?: algosdk.TransactionSigner | TransactionSignerAccount + /** Change the signing key of the sender to the given address */ + rekeyTo?: string + /** Note to attach to the transaction*/ + note?: Uint8Array | string + /** Prevent multiple transactions with the same lease being included within the validity window */ + lease?: Uint8Array | string + /** The transaction fee. In most cases you want to use `extraFee` unless setting the fee to 0 to be covered by another transaction */ + staticFee?: AlgoAmount + /** The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees */ + extraFee?: AlgoAmount + /** Throw an error if the fee for the transaction is more than this amount */ + maxFee?: AlgoAmount + /** How many rounds the transaction should be valid for */ + validityWindow?: number + /** + * Set the first round this transaction is valid. + * If left undefined, the value from algod will be used. + * Only set this when you intentionally want this to be some time in the future + */ + firstValidRound?: bigint + /** The last round this transaction is valid. It is recommended to use validityWindow instead */ + lastValidRound?: bigint +} + +/** Parameters to define a payment transaction. */ +export type PaymentParams = CommonTransactionParams & { + /** That account that will receive the ALGO */ + receiver: string + /** Amount to send */ + amount: AlgoAmount + /** If given, close the sender account and send the remaining balance to this address */ + closeRemainderTo?: string +} + +/** Parameters to define an asset create transaction. */ +export type AssetCreateParams = CommonTransactionParams & { + /** The total amount of the smallest divisible unit to create */ + total: bigint + /** The amount of decimal places the asset should have */ + decimals?: number + /** Whether the asset is frozen by default in the creator address */ + defaultFrozen?: boolean + /** The address that can change the manager, reserve, clawback, and freeze addresses. There will permanently be no manager if undefined or an empty string */ + manager?: string + /** The address that holds the uncirculated supply */ + reserve?: string + /** The address that can freeze the asset in any account. Freezing will be permanently disabled if undefined or an empty string. */ + freeze?: string + /** The address that can clawback the asset from any account. Clawback will be permanently disabled if undefined or an empty string. */ + clawback?: string + /** The short ticker name for the asset */ + unitName?: string + /** The full name of the asset */ + assetName?: string + /** The metadata URL for the asset */ + url?: string + /** Hash of the metadata contained in the metadata URL */ + metadataHash?: Uint8Array +} + +/** Parameters to define an asset config transaction. */ +export type AssetConfigParams = CommonTransactionParams & { + /** ID of the asset */ + assetId: bigint + /** The address that can change the manager, reserve, clawback, and freeze addresses. There will permanently be no manager if undefined or an empty string */ + manager?: string + /** The address that holds the uncirculated supply */ + reserve?: string + /** The address that can freeze the asset in any account. Freezing will be permanently disabled if undefined or an empty string. */ + freeze?: string + /** The address that can clawback the asset from any account. Clawback will be permanently disabled if undefined or an empty string. */ + clawback?: string +} + +/** Parameters to define an asset freeze transaction. */ +export type AssetFreezeParams = CommonTransactionParams & { + /** The ID of the asset */ + assetId: bigint + /** The account to freeze or unfreeze */ + account: string + /** Whether the assets in the account should be frozen */ + frozen: boolean +} + +/** Parameters to define an asset destroy transaction. */ +export type AssetDestroyParams = CommonTransactionParams & { + /** ID of the asset */ + assetId: bigint +} + +/** Parameters to define an asset transfer transaction. */ +export type AssetTransferParams = CommonTransactionParams & { + /** ID of the asset */ + assetId: bigint + /** Amount of the asset to transfer (smallest divisible unit) */ + amount: bigint + /** The account to send the asset to */ + receiver: string + /** The account to take the asset from */ + clawbackTarget?: string + /** The account to close the asset to */ + closeAssetTo?: string +} + +/** Parameters to define an asset opt-in transaction. */ +export type AssetOptInParams = CommonTransactionParams & { + /** ID of the asset */ + assetId: bigint +} + +/** Parameters to define an online key registration transaction. */ +export type OnlineKeyRegistrationParams = CommonTransactionParams & { + /** The root participation public key */ + voteKey: Uint8Array + /** The VRF public key */ + selectionKey: Uint8Array + /** The first round that the participation key is valid. Not to be confused with the `firstValid` round of the keyreg transaction */ + voteFirst: bigint + /** The last round that the participation key is valid. Not to be confused with the `lastValid` round of the keyreg transaction */ + voteLast: bigint + /** This is the dilution for the 2-level participation key. It determines the interval (number of rounds) for generating new ephemeral keys */ + voteKeyDilution: bigint + /** The 64 byte state proof public key commitment */ + stateProofKey?: Uint8Array +} + +// Not yet exposed because of bug in algosdk +// export type OfflineKeyRegistrationParams = CommonTransactionParams & { +// /** Prevent this account from ever participating again. On network with rewards enabled, also disable rewards for this account */ +// preventAddressFromEverParticipatingAgain?: boolean +// } + +/** Parameters to define an application call transaction. */ +export type AppCallParams = CommonTransactionParams & { + /** The [OnComplete](https://developer.algorand.org/docs/get-details/dapps/avm/teal/specification/#oncomplete) */ + onComplete?: algosdk.OnApplicationComplete + /** ID of the application */ + appId?: bigint + /** The program to execute for all OnCompletes other than ClearState */ + approvalProgram?: Uint8Array + /** The program to execute for ClearState OnComplete */ + clearProgram?: Uint8Array + /** The state schema for the app. This is immutable. */ + schema?: { + /** The number of integers saved in global state */ + globalUints: number + /** The number of byte slices saved in global state */ + globalByteSlices: number + /** The number of integers saved in local state */ + localUints: number + /** The number of byte slices saved in local state */ + localByteSlices: number + } + /** Application arguments */ + args?: Uint8Array[] + /** Account references */ + accountReferences?: string[] + /** App references */ + appReferences?: bigint[] + /** Asset references */ + assetReferences?: bigint[] + /** Number of extra pages required for the programs */ + extraPages?: number + /** Box references */ + boxReferences?: algosdk.BoxReference[] +} + +/** Parameters to define an ABI method application call transaction. */ +export type MethodCallParams = CommonTransactionParams & + Omit & { + /** ID of the application */ + appId: bigint + /** The ABI method to call */ + method: algosdk.ABIMethod + /** Arguments to the ABI method, either: + * * An ABI value + * * A transaction with explicit signer + * * A transaction (where the signer will be automatically assigned) + * * An unawaited transaction (e.g. from algorand.transactions.transactionType()) + * * Another method call (via method call params object) + */ + args?: (algosdk.ABIValue | TransactionWithSigner | Transaction | Promise | MethodCallParams)[] + } + +type Txn = + | (PaymentParams & { type: 'pay' }) + | (AssetCreateParams & { type: 'assetCreate' }) + | (AssetConfigParams & { type: 'assetConfig' }) + | (AssetFreezeParams & { type: 'assetFreeze' }) + | (AssetDestroyParams & { type: 'assetDestroy' }) + | (AssetTransferParams & { type: 'assetTransfer' }) + | (AssetOptInParams & { type: 'assetOptIn' }) + | (AppCallParams & { type: 'appCall' }) + | (OnlineKeyRegistrationParams & { type: 'keyReg' }) + | (algosdk.TransactionWithSigner & { type: 'txnWithSigner' }) + | { atc: algosdk.AtomicTransactionComposer; type: 'atc' } + | (MethodCallParams & { type: 'methodCall' }) + +/** Parameters to configure transaction execution. */ +export interface ExecuteParams { + /** The number of rounds to wait for confirmation. By default until the latest lastValid has past. */ + maxRoundsToWaitForConfirmation?: number + /** Whether to suppress log messages from transaction send, default: do not suppress */ + suppressLog?: boolean +} + +/** Parameters to create an `AlgokitComposer`. */ +export type AlgokitComposerParams = { + /** The algod client to use to get suggestedParams and send the transaction group */ + algod: algosdk.Algodv2 + /** The function used to get the TransactionSigner for a given address */ + getSigner: (address: string) => algosdk.TransactionSigner + /** The method used to get SuggestedParams for transactions in the group */ + getSuggestedParams?: () => Promise + /** How many rounds a transaction should be valid for by default */ + defaultValidityWindow?: number +} + +/** AlgoKit Composer helps you compose and execute transactions as a transaction group. + * + * Note: this class is a new Beta feature and may be subject to change. + * + * @beta + */ +export default class AlgokitComposer { + /** The ATC used to compose the group */ + private atc = new algosdk.AtomicTransactionComposer() + + /** Map of txid to ABI method */ + private txnMethodMap: Map = new Map() + + /** Transactions that have not yet been composed */ + private txns: Txn[] = [] + + /** The algod client used by the composer. */ + private algod: algosdk.Algodv2 + + /** An async function that will return suggestedParams. */ + private getSuggestedParams: () => Promise + + /** A function that takes in an address and return a signer function for that address. */ + private getSigner: (address: string) => algosdk.TransactionSigner + + /** The default transaction validity window */ + private defaultValidityWindow = 10 + + /** + * Create an `AlgoKitComposer`. + * @param params The configuration for this composer + */ + constructor(params: AlgokitComposerParams) { + this.algod = params.algod + const defaultGetSuggestedParams = () => params.algod.getTransactionParams().do() + this.getSuggestedParams = params.getSuggestedParams ?? defaultGetSuggestedParams + this.getSigner = params.getSigner + this.defaultValidityWindow = params.defaultValidityWindow ?? this.defaultValidityWindow + } + + /** + * Add a payment transaction to the transaction group. + * @param params The payment transaction parameters + * @returns The composer so you can chain method calls + */ + addPayment(params: PaymentParams): AlgokitComposer { + this.txns.push({ ...params, type: 'pay' }) + + return this + } + + /** + * Add an asset create transaction to the transaction group. + * @param params The asset create transaction parameters + * @returns The composer so you can chain method calls + */ + addAssetCreate(params: AssetCreateParams): AlgokitComposer { + this.txns.push({ ...params, type: 'assetCreate' }) + + return this + } + + /** + * Add an asset config transaction to the transaction group. + * @param params The asset config transaction parameters + * @returns The composer so you can chain method calls + */ + addAssetConfig(params: AssetConfigParams): AlgokitComposer { + this.txns.push({ ...params, type: 'assetConfig' }) + + return this + } + + /** + * Add an asset freeze transaction to the transaction group. + * @param params The asset freeze transaction parameters + * @returns The composer so you can chain method calls + */ + addAssetFreeze(params: AssetFreezeParams): AlgokitComposer { + this.txns.push({ ...params, type: 'assetFreeze' }) + + return this + } + + /** + * Add an asset destroy transaction to the transaction group. + * @param params The asset destroy transaction parameters + * @returns The composer so you can chain method calls + */ + addAssetDestroy(params: AssetDestroyParams): AlgokitComposer { + this.txns.push({ ...params, type: 'assetDestroy' }) + + return this + } + + /** + * Add an asset transfer transaction to the transaction group. + * @param params The asset transfer transaction parameters + * @returns The composer so you can chain method calls + */ + addAssetTransfer(params: AssetTransferParams): AlgokitComposer { + this.txns.push({ ...params, type: 'assetTransfer' }) + + return this + } + + /** + * Add an asset opt-in transaction to the transaction group. + * @param params The asset opt-in transaction parameters + * @returns The composer so you can chain method calls + */ + addAssetOptIn(params: AssetOptInParams): AlgokitComposer { + this.txns.push({ ...params, type: 'assetOptIn' }) + + return this + } + + /** + * Add an application call transaction to the transaction group. + * + * Note: we recommend using app clients to make it easier to make app calls. + * @param params The application call transaction parameters + * @returns The composer so you can chain method calls + */ + addAppCall(params: AppCallParams): AlgokitComposer { + this.txns.push({ ...params, type: 'appCall' }) + + return this + } + + /** + * Add an ABI method application call transaction to the transaction group. + * + * Note: we recommend using app clients to make it easier to make app calls. + * @param params The ABI method application call transaction parameters + * @returns The composer so you can chain method calls + */ + addMethodCall(params: MethodCallParams) { + this.txns.push({ ...params, type: 'methodCall' }) + return this + } + + /** + * Add an online key registration transaction to the transaction group. + * @param params The online key registration transaction parameters + * @returns The composer so you can chain method calls + */ + addOnlineKeyRegistration(params: OnlineKeyRegistrationParams): AlgokitComposer { + this.txns.push({ ...params, type: 'keyReg' }) + + return this + } + + /** + * Add the transactions within an `AtomicTransactionComposer` to the transaction group. + * @param atc The `AtomicTransactionComposer` to build transactions from and add to the group + * @returns The composer so you can chain method calls + */ + addAtc(atc: algosdk.AtomicTransactionComposer): AlgokitComposer { + this.txns.push({ atc, type: 'atc' }) + return this + } + + private buildAtc(atc: algosdk.AtomicTransactionComposer): algosdk.TransactionWithSigner[] { + const group = atc.buildGroup() + + const txnWithSigners = group.map((ts) => { + ts.txn.group = undefined + return ts + }) + + const method = atc['methodCalls'].get(group.length - 1) + if (method) this.txnMethodMap.set(txnWithSigners.at(-1)!.txn.txID(), method) + + return txnWithSigners + } + + private commonTxnBuildStep(params: CommonTransactionParams, txn: algosdk.Transaction, suggestedParams: algosdk.SuggestedParams) { + if (params.lease) txn.addLease(encodeLease(params.lease)!) + if (params.rekeyTo) txn.addRekey(params.rekeyTo) + if (params.note) txn.note = encodeTransactionNote(params.note) + + if (params.firstValidRound) { + txn.firstRound = Number(params.firstValidRound) + } + + if (params.lastValidRound) { + txn.lastRound = Number(params.lastValidRound) + } else { + txn.lastRound = txn.firstRound + (params.validityWindow ?? this.defaultValidityWindow) + } + + if (params.staticFee !== undefined && params.extraFee !== undefined) { + throw Error('Cannot set both staticFee and extraFee') + } + + if (params.staticFee !== undefined) { + txn.fee = params.staticFee.microAlgos + } else { + txn.fee = txn.estimateSize() * suggestedParams.fee || algosdk.ALGORAND_MIN_TX_FEE + if (params.extraFee) txn.fee += params.extraFee.microAlgos + } + txn.flatFee = true + + if (params.maxFee !== undefined && txn.fee > params.maxFee.microAlgos) { + throw Error(`Transaction fee ${txn.fee} is greater than maxFee ${params.maxFee}`) + } + + return txn + } + + private async buildMethodCall( + params: MethodCallParams, + suggestedParams: algosdk.SuggestedParams, + ): Promise { + const methodArgs: algosdk.ABIArgument[] = [] + const isAbiValue = (x: unknown): x is algosdk.ABIValue => { + if (Array.isArray(x)) return x.length == 0 || x.every(isAbiValue) + + return ['boolean', 'number', 'bigint', 'string', 'Uint8Array'].includes(typeof x) + } + + for (const arg of params.args ?? []) { + if (isAbiValue(arg)) { + methodArgs.push(arg) + continue + } + + if (isTransactionWithSigner(arg)) { + methodArgs.push(arg) + continue + } + + if ('method' in arg) { + const tempTxnWithSigners = await this.buildMethodCall(arg, suggestedParams) + methodArgs.push(...tempTxnWithSigners) + continue + } + + const txn = await arg + methodArgs.push({ + txn, + signer: params.signer + ? 'signer' in params.signer + ? params.signer.signer + : params.signer + : this.getSigner(encodeAddress(txn.from.publicKey)), + }) + } + + const methodAtc = new algosdk.AtomicTransactionComposer() + + methodAtc.addMethodCall({ + ...params, + appID: Number(params.appId || 0), + suggestedParams, + signer: params.signer ? ('signer' in params.signer ? params.signer.signer : params.signer) : this.getSigner(params.sender), + methodArgs: methodArgs, + // note, lease, and rekeyTo are set in the common build step + note: undefined, + lease: undefined, + rekeyTo: undefined, + }) + + // Run the actual method call txn through the common build step to set fees and validity rounds + const group = methodAtc.buildGroup() + const methodIdx = group.length - 1 + group[methodIdx].txn = this.commonTxnBuildStep(params, group[methodIdx].txn, suggestedParams) + + return this.buildAtc(methodAtc) + } + + private buildPayment(params: PaymentParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({ + from: params.sender, + to: params.receiver, + amount: params.amount.microAlgos, + closeRemainderTo: params.closeRemainderTo, + suggestedParams, + }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildAssetCreate(params: AssetCreateParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({ + from: params.sender, + total: params.total, + decimals: params.decimals ?? 0, + assetName: params.assetName, + unitName: params.unitName, + assetURL: params.url, + defaultFrozen: params.defaultFrozen ?? false, + assetMetadataHash: params.metadataHash, + manager: params.manager, + reserve: params.reserve, + freeze: params.freeze, + clawback: params.clawback, + suggestedParams, + }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildAssetConfig(params: AssetConfigParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makeAssetConfigTxnWithSuggestedParamsFromObject({ + from: params.sender, + assetIndex: Number(params.assetId), + suggestedParams, + manager: params.manager, + reserve: params.reserve, + freeze: params.freeze, + clawback: params.clawback, + strictEmptyAddressChecking: false, + }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildAssetDestroy(params: AssetDestroyParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makeAssetDestroyTxnWithSuggestedParamsFromObject({ + from: params.sender, + assetIndex: Number(params.assetId), + suggestedParams, + }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildAssetFreeze(params: AssetFreezeParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makeAssetFreezeTxnWithSuggestedParamsFromObject({ + from: params.sender, + assetIndex: Number(params.assetId), + freezeTarget: params.account, + freezeState: params.frozen, + suggestedParams, + }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildAssetTransfer(params: AssetTransferParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({ + from: params.sender, + to: params.receiver, + assetIndex: Number(params.assetId), + amount: params.amount, + suggestedParams, + closeRemainderTo: params.closeAssetTo, + revocationTarget: params.clawbackTarget, + }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildAppCall(params: AppCallParams, suggestedParams: algosdk.SuggestedParams) { + const sdkParams = { + from: params.sender, + suggestedParams, + onComplete: params.onComplete, + approvalProgram: params.approvalProgram, + clearProgram: params.clearProgram, + appArgs: params.args, + accounts: params.accountReferences, + foreignApps: params.appReferences?.map((x) => Number(x)), + foreignAssets: params.assetReferences?.map((x) => Number(x)), + extraPages: params.extraPages, + numLocalInts: params.schema?.localUints || 0, + numLocalByteSlices: params.schema?.localByteSlices || 0, + numGlobalInts: params.schema?.globalUints || 0, + numGlobalByteSlices: params.schema?.globalByteSlices || 0, + } + + let txn: algosdk.Transaction + + const onComplete = params.onComplete || algosdk.OnApplicationComplete.NoOpOC + + if (!params.appId) { + if (params.approvalProgram === undefined || params.clearProgram === undefined) { + throw new Error('approvalProgram and clearProgram are required for application creation') + } + + txn = algosdk.makeApplicationCreateTxnFromObject({ + ...sdkParams, + onComplete, + approvalProgram: params.approvalProgram, + clearProgram: params.clearProgram, + }) + } + + txn = algosdk.makeApplicationCallTxnFromObject({ ...sdkParams, onComplete, appIndex: Number(params.appId || 0) }) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private buildKeyReg(params: OnlineKeyRegistrationParams, suggestedParams: algosdk.SuggestedParams) { + const txn = algosdk.makeKeyRegistrationTxnWithSuggestedParams( + params.sender, + undefined, + params.voteKey, + params.selectionKey, + Number(params.voteFirst), + Number(params.voteLast), + Number(params.voteKeyDilution), + suggestedParams, + undefined, + false, + params.stateProofKey, + ) + + return this.commonTxnBuildStep(params, txn, suggestedParams) + } + + private async buildTxn(txn: Txn, suggestedParams: algosdk.SuggestedParams): Promise { + if (txn.type === 'txnWithSigner') { + return [txn] + } + + if (txn.type === 'atc') { + return this.buildAtc(txn.atc) + } + + if (txn.type === 'methodCall') { + return await this.buildMethodCall(txn, suggestedParams) + } + + const signer = txn.signer ? ('signer' in txn.signer ? txn.signer.signer : txn.signer) : this.getSigner(txn.sender) + + switch (txn.type) { + case 'pay': { + const payment = this.buildPayment(txn, suggestedParams) + return [{ txn: payment, signer }] + } + case 'assetCreate': { + const assetCreate = this.buildAssetCreate(txn, suggestedParams) + return [{ txn: assetCreate, signer }] + } + case 'appCall': { + const appCall = this.buildAppCall(txn, suggestedParams) + return [{ txn: appCall, signer }] + } + case 'assetConfig': { + const assetConfig = this.buildAssetConfig(txn, suggestedParams) + return [{ txn: assetConfig, signer }] + } + case 'assetDestroy': { + const assetDestroy = this.buildAssetDestroy(txn, suggestedParams) + return [{ txn: assetDestroy, signer }] + } + case 'assetFreeze': { + const assetFreeze = this.buildAssetFreeze(txn, suggestedParams) + return [{ txn: assetFreeze, signer }] + } + case 'assetTransfer': { + const assetTransfer = this.buildAssetTransfer(txn, suggestedParams) + return [{ txn: assetTransfer, signer }] + } + case 'assetOptIn': { + const assetTransfer = this.buildAssetTransfer({ ...txn, receiver: txn.sender, amount: 0n }, suggestedParams) + return [{ txn: assetTransfer, signer }] + } + case 'keyReg': { + const keyReg = this.buildKeyReg(txn, suggestedParams) + return [{ txn: keyReg, signer }] + } + default: + throw Error(`Unsupported txn type`) + } + } + + /** + * Compose all of the transactions in a single atomic transaction group and an atomic transaction composer. + * + * You can then use the transactions standalone, or use the composer to execute or simulate the transactions. + * @returns The built atomic transaction composer and the transactions + */ + async build() { + if (this.atc.getStatus() === algosdk.AtomicTransactionComposerStatus.BUILDING) { + const suggestedParams = await this.getSuggestedParams() + + const txnWithSigners: algosdk.TransactionWithSigner[] = [] + + for (const txn of this.txns) { + txnWithSigners.push(...(await this.buildTxn(txn, suggestedParams))) + } + + txnWithSigners.forEach((ts) => { + this.atc.addTransaction(ts) + }) + + const methodCalls = new Map() + + txnWithSigners.forEach((ts, idx) => { + const method = this.txnMethodMap.get(ts.txn.txID()) + if (method) methodCalls.set(idx, method) + }) + + this.atc['methodCalls'] = methodCalls + } + + return { atc: this.atc, transactions: this.atc.buildGroup() } + } + + /** + * Rebuild the group, discarding any previously built transactions. + * This will potentially cause new signers and suggested params to be used if the callbacks return a new value compared to the first build. + * @returns The newly built atomic transaction composer and the transactions + */ + async rebuild() { + this.atc = new algosdk.AtomicTransactionComposer() + return await this.build() + } + + /** + * Compose the atomic transaction group and send it to the network + * @param params The parameters to control execution with + * @returns The execution result + */ + async execute(params?: ExecuteParams): Promise { + const group = (await this.build()).transactions + + let waitRounds = params?.maxRoundsToWaitForConfirmation + if (waitRounds === undefined) { + const lastRound = group.reduce((max, txn) => Math.max(txn.txn.lastRound, max), 0) + const { firstRound } = await this.getSuggestedParams() + waitRounds = lastRound - firstRound + 1 + } + + return await sendAtomicTransactionComposer( + { + atc: this.atc, + sendParams: { suppressLog: params?.suppressLog, maxRoundsToWaitForConfirmation: waitRounds }, + }, + this.algod, + ) + } +} diff --git a/src/types/network-client.ts b/src/types/network-client.ts index 42580d13..89a72714 100644 --- a/src/types/network-client.ts +++ b/src/types/network-client.ts @@ -15,7 +15,7 @@ export interface AlgoConfig { /** Algo client configuration */ algodConfig: AlgoClientConfig /** Indexer client configuration */ - indexerConfig: AlgoClientConfig + indexerConfig?: AlgoClientConfig /** Kmd configuration */ - kmdConfig: AlgoClientConfig + kmdConfig?: AlgoClientConfig } diff --git a/src/types/testing.ts b/src/types/testing.ts index 7bd191ae..072a8946 100644 --- a/src/types/testing.ts +++ b/src/types/testing.ts @@ -3,6 +3,8 @@ import { TransactionLogger } from '../testing' import { TestLogger } from '../testing/test-logger' import { AlgoAmount } from '../types/amount' import { SendTransactionFrom } from '../types/transaction' +import { TransactionSignerAccount } from './account' +import AlgorandClient from './algorand-client' import { TransactionLookupResult } from './indexer' import Account = algosdk.Account import Algodv2 = algosdk.Algodv2 @@ -23,9 +25,9 @@ export interface AlgorandTestAutomationContext { /** Transaction logger that will log transaction IDs for all transactions issued by `algod` */ transactionLogger: TransactionLogger /** Default, funded test account that is ephemerally created */ - testAccount: Account + testAccount: Account & TransactionSignerAccount /** Generate and fund an additional ephemerally created account */ - generateAccount: (params: GetTestAccountParams) => Promise + generateAccount: (params: GetTestAccountParams) => Promise /** Wait for the indexer to catch up with all transactions logged by `transactionLogger` */ waitForIndexer: () => Promise /** Wait for the indexer to catch up with the given transaction ID */ @@ -72,6 +74,11 @@ export interface AlgorandFixture { */ get context(): AlgorandTestAutomationContext + /** + * Retrieve an `AlgorandClient` loaded with the current context, including testAccount and any generated accounts loaded as signers. + */ + get algorand(): AlgorandClient + /** * Testing framework agnostic handler method to run before each test to prepare the `context` for that test. */ diff --git a/src/types/transaction.ts b/src/types/transaction.ts index e9b090cf..f04d9426 100644 --- a/src/types/transaction.ts +++ b/src/types/transaction.ts @@ -71,6 +71,10 @@ export interface SendAtomicTransactionComposerResults extends SendTransactionRes txIds: string[] /** If ABI method(s) were called the processed return values */ returns?: ABIReturn[] + /** The responses if the transactions were sent and waited for, + * the index of the confirmation will match the index of the underlying transaction + */ + confirmations: modelsv2.PendingTransactionResponse[] } /** The result of sending and confirming a transaction */ diff --git a/tests/example-contracts/client/TestContractClient.ts b/tests/example-contracts/client/TestContractClient.ts new file mode 100644 index 00000000..f3ec98c5 --- /dev/null +++ b/tests/example-contracts/client/TestContractClient.ts @@ -0,0 +1,826 @@ +/* eslint-disable */ +/** + * This file was automatically generated by @algorandfoundation/algokit-client-generator. + * DO NOT MODIFY IT BY HAND. + * requires: @algorandfoundation/algokit-utils: ^2 + */ +import type { ABIResult, TransactionWithSigner } from 'algosdk' +import { Algodv2, AtomicTransactionComposer, OnApplicationComplete, Transaction, modelsv2 } from 'algosdk' +import * as algokit from '../../../src/index' +import type { + ABIAppCallArg, + AppCallTransactionResult, + AppCallTransactionResultOfType, + AppCompilationResult, + AppReference, + CoreAppCallArgs, + RawAppCallArgs, + TealTemplateParams +} from '../../../src/types/app' +import type { + AppClientCallCoreParams, + AppClientCompilationParams, + AppClientDeployCoreParams, + AppDetails, + ApplicationClient, +} from '../../../src/types/app-client' +import type { AppSpec } from '../../../src/types/app-spec' +import type { SendTransactionFrom, SendTransactionParams, SendTransactionResult, TransactionToSign } from '../../../src/types/transaction' +export const APP_SPEC: AppSpec = { + "hints": { + "doMath(uint64,uint64,string)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "txnArg(pay)address": { + "call_config": { + "no_op": "CALL" + } + }, + "helloWorld()string": { + "call_config": { + "no_op": "CALL" + } + }, + "methodArg(appl)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "nestedTxnArg(pay,appl)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "doubleNestedTxnArg(pay,appl,pay,appl)uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "createApplication()void": { + "call_config": { + "no_op": "CREATE" + } + } + }, + "bare_call_config": { + "no_op": "NEVER", + "opt_in": "NEVER", + "close_out": "NEVER", + "update_application": "NEVER", + "delete_application": "NEVER" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgovLyBUaGlzIFRFQUwgd2FzIGdlbmVyYXRlZCBieSBURUFMU2NyaXB0IHYwLjg2LjAKLy8gaHR0cHM6Ly9naXRodWIuY29tL2FsZ29yYW5kZm91bmRhdGlvbi9URUFMU2NyaXB0CgovLyBUaGlzIGNvbnRyYWN0IGlzIGNvbXBsaWFudCB3aXRoIGFuZC9vciBpbXBsZW1lbnRzIHRoZSBmb2xsb3dpbmcgQVJDczogWyBBUkM0IF0KCi8vIFRoZSBmb2xsb3dpbmcgdGVuIGxpbmVzIG9mIFRFQUwgaGFuZGxlIGluaXRpYWwgcHJvZ3JhbSBmbG93Ci8vIFRoaXMgcGF0dGVybiBpcyB1c2VkIHRvIG1ha2UgaXQgZWFzeSBmb3IgYW55b25lIHRvIHBhcnNlIHRoZSBzdGFydCBvZiB0aGUgcHJvZ3JhbSBhbmQgZGV0ZXJtaW5lIGlmIGEgc3BlY2lmaWMgYWN0aW9uIGlzIGFsbG93ZWQKLy8gSGVyZSwgYWN0aW9uIHJlZmVycyB0byB0aGUgT25Db21wbGV0ZSBpbiBjb21iaW5hdGlvbiB3aXRoIHdoZXRoZXIgdGhlIGFwcCBpcyBiZWluZyBjcmVhdGVkIG9yIGNhbGxlZAovLyBFdmVyeSBwb3NzaWJsZSBhY3Rpb24gZm9yIHRoaXMgY29udHJhY3QgaXMgcmVwcmVzZW50ZWQgaW4gdGhlIHN3aXRjaCBzdGF0ZW1lbnQKLy8gSWYgdGhlIGFjdGlvbiBpcyBub3QgaW1wbGVtZW50ZWQgaW4gdGhlIGNvbnRyYWN0LCBpdHMgcmVzcGVjdGl2ZSBicmFuY2ggd2lsbCBiZSAiKk5PVF9JTVBMRU1FTlRFRCIgd2hpY2gganVzdCBjb250YWlucyAiZXJyIgp0eG4gQXBwbGljYXRpb25JRAohCmludCA2CioKdHhuIE9uQ29tcGxldGlvbgorCnN3aXRjaCAqY2FsbF9Ob09wICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVEICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqY3JlYXRlX05vT3AgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVEICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVECgoqTk9UX0lNUExFTUVOVEVEOgoJZXJyCgovLyBnZXRTdW0oYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIKLy8KLy8gQ2FsY3VsYXRlcyB0aGUgc3VtIG9mIHR3byBudW1iZXJzCi8vCi8vIEBwYXJhbSBhCi8vIEBwYXJhbSBiCi8vIEByZXR1cm5zIFRoZSBzdW0gb2YgYSBhbmQgYgpnZXRTdW06Cglwcm90byAyIDEKCgkvLyB0ZXN0X2NvbnRyYWN0L3Rlc3QuYWxnby50czoxMgoJLy8gcmV0dXJuIGEgKyBiOwoJZnJhbWVfZGlnIC0xIC8vIGE6IG51bWJlcgoJZnJhbWVfZGlnIC0yIC8vIGI6IG51bWJlcgoJKwoJcmV0c3ViCgovLyBnZXREaWZmZXJlbmNlKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyCi8vCi8vIENhbGN1bGF0ZXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gbnVtYmVycwovLwovLyBAcGFyYW0gYQovLyBAcGFyYW0gYgovLyBAcmV0dXJucyBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGEgYW5kIGIuCmdldERpZmZlcmVuY2U6Cglwcm90byAyIDEKCgkvLyB0ZXN0X2NvbnRyYWN0L3Rlc3QuYWxnby50czoyMwoJLy8gcmV0dXJuIGEgPj0gYiA/IGEgLSBiIDogYiAtIGE7CglmcmFtZV9kaWcgLTEgLy8gYTogbnVtYmVyCglmcmFtZV9kaWcgLTIgLy8gYjogbnVtYmVyCgk+PQoJYnogKnRlcm5hcnkwX2ZhbHNlCglmcmFtZV9kaWcgLTEgLy8gYTogbnVtYmVyCglmcmFtZV9kaWcgLTIgLy8gYjogbnVtYmVyCgktCgliICp0ZXJuYXJ5MF9lbmQKCip0ZXJuYXJ5MF9mYWxzZToKCWZyYW1lX2RpZyAtMiAvLyBiOiBudW1iZXIKCWZyYW1lX2RpZyAtMSAvLyBhOiBudW1iZXIKCS0KCip0ZXJuYXJ5MF9lbmQ6CglyZXRzdWIKCi8vIGRvTWF0aCh1aW50NjQsdWludDY0LHN0cmluZyl1aW50NjQKKmFiaV9yb3V0ZV9kb01hdGg6CgkvLyBUaGUgQUJJIHJldHVybiBwcmVmaXgKCWJ5dGUgMHgxNTFmN2M3NQoKCS8vIG9wZXJhdGlvbjogc3RyaW5nCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAzCglleHRyYWN0IDIgMAoKCS8vIGI6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIGE6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoKCS8vIGV4ZWN1dGUgZG9NYXRoKHVpbnQ2NCx1aW50NjQsc3RyaW5nKXVpbnQ2NAoJY2FsbHN1YiBkb01hdGgKCWl0b2IKCWNvbmNhdAoJbG9nCglpbnQgMQoJcmV0dXJuCgovLyBkb01hdGgoYTogbnVtYmVyLCBiOiBudW1iZXIsIG9wZXJhdGlvbjogc3RyaW5nKTogbnVtYmVyCi8vCi8vIEEgbWV0aG9kIHRoYXQgdGFrZXMgdHdvIG51bWJlcnMgYW5kIGRvZXMgZWl0aGVyIGFkZGl0aW9uIG9yIHN1YnRyYWN0aW9uCi8vCi8vIEBwYXJhbSBhIFRoZSBmaXJzdCBudW1iZXIKLy8gQHBhcmFtIGIgVGhlIHNlY29uZCBudW1iZXIKLy8gQHBhcmFtIG9wZXJhdGlvbiBUaGUgb3BlcmF0aW9uIHRvIHBlcmZvcm0uIENhbiBiZSBlaXRoZXIgJ3N1bScgb3IgJ2RpZmZlcmVuY2UnCi8vCi8vIEByZXR1cm5zIFRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbgpkb01hdGg6Cglwcm90byAzIDEKCgkvLyBQdXNoIGVtcHR5IGJ5dGVzIGFmdGVyIHRoZSBmcmFtZSBwb2ludGVyIHRvIHJlc2VydmUgc3BhY2UgZm9yIGxvY2FsIHZhcmlhYmxlcwoJYnl0ZSAweAoKCS8vICppZjBfY29uZGl0aW9uCgkvLyB0ZXN0X2NvbnRyYWN0L3Rlc3QuYWxnby50czozOAoJLy8gb3BlcmF0aW9uID09PSAnc3VtJwoJZnJhbWVfZGlnIC0zIC8vIG9wZXJhdGlvbjogc3RyaW5nCglieXRlIDB4NzM3NTZkIC8vICJzdW0iCgk9PQoJYnogKmlmMF9lbHNlaWYxX2NvbmRpdGlvbgoKCS8vICppZjBfY29uc2VxdWVudAoJLy8gdGVzdF9jb250cmFjdC90ZXN0LmFsZ28udHM6MzkKCS8vIHJlc3VsdCA9IHRoaXMuZ2V0U3VtKGEsIGIpCglmcmFtZV9kaWcgLTIgLy8gYjogbnVtYmVyCglmcmFtZV9kaWcgLTEgLy8gYTogbnVtYmVyCgljYWxsc3ViIGdldFN1bQoJZnJhbWVfYnVyeSAwIC8vIHJlc3VsdDogbnVtYmVyCgliICppZjBfZW5kCgoqaWYwX2Vsc2VpZjFfY29uZGl0aW9uOgoJLy8gdGVzdF9jb250cmFjdC90ZXN0LmFsZ28udHM6NDAKCS8vIG9wZXJhdGlvbiA9PT0gJ2RpZmZlcmVuY2UnCglmcmFtZV9kaWcgLTMgLy8gb3BlcmF0aW9uOiBzdHJpbmcKCWJ5dGUgMHg2NDY5NjY2NjY1NzI2NTZlNjM2NSAvLyAiZGlmZmVyZW5jZSIKCT09CglieiAqaWYwX2Vsc2UKCgkvLyAqaWYwX2Vsc2VpZjFfY29uc2VxdWVudAoJLy8gdGVzdF9jb250cmFjdC90ZXN0LmFsZ28udHM6NDEKCS8vIHJlc3VsdCA9IHRoaXMuZ2V0RGlmZmVyZW5jZShhLCBiKQoJZnJhbWVfZGlnIC0yIC8vIGI6IG51bWJlcgoJZnJhbWVfZGlnIC0xIC8vIGE6IG51bWJlcgoJY2FsbHN1YiBnZXREaWZmZXJlbmNlCglmcmFtZV9idXJ5IDAgLy8gcmVzdWx0OiBudW1iZXIKCWIgKmlmMF9lbmQKCippZjBfZWxzZToKCWVyciAvLyAnSW52YWxpZCBvcGVyYXRpb24nCgoqaWYwX2VuZDoKCS8vIHRlc3RfY29udHJhY3QvdGVzdC5hbGdvLnRzOjQ0CgkvLyByZXR1cm4gcmVzdWx0OwoJZnJhbWVfZGlnIDAgLy8gcmVzdWx0OiBudW1iZXIKCgkvLyBzZXQgdGhlIHN1YnJvdXRpbmUgcmV0dXJuIHZhbHVlCglmcmFtZV9idXJ5IDAKCXJldHN1YgoKLy8gdHhuQXJnKHBheSlhZGRyZXNzCiphYmlfcm91dGVfdHhuQXJnOgoJLy8gVGhlIEFCSSByZXR1cm4gcHJlZml4CglieXRlIDB4MTUxZjdjNzUKCgkvLyB0eG46IHBheQoJdHhuIEdyb3VwSW5kZXgKCWludCAxCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgcGF5Cgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSB0eG5BcmcocGF5KWFkZHJlc3MKCWNhbGxzdWIgdHhuQXJnCgljb25jYXQKCWxvZwoJaW50IDEKCXJldHVybgoKLy8gdHhuQXJnKHR4bjogUGF5VHhuKTogQWRkcmVzcwp0eG5Bcmc6Cglwcm90byAxIDEKCgkvLyB0ZXN0X2NvbnRyYWN0L3Rlc3QuYWxnby50czo0OAoJLy8gcmV0dXJuIHR4bi5zZW5kZXI7CglmcmFtZV9kaWcgLTEgLy8gdHhuOiBQYXlUeG4KCWd0eG5zIFNlbmRlcgoJcmV0c3ViCgovLyBoZWxsb1dvcmxkKClzdHJpbmcKKmFiaV9yb3V0ZV9oZWxsb1dvcmxkOgoJLy8gVGhlIEFCSSByZXR1cm4gcHJlZml4CglieXRlIDB4MTUxZjdjNzUKCgkvLyBleGVjdXRlIGhlbGxvV29ybGQoKXN0cmluZwoJY2FsbHN1YiBoZWxsb1dvcmxkCglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJY29uY2F0Cglsb2cKCWludCAxCglyZXR1cm4KCi8vIGhlbGxvV29ybGQoKTogc3RyaW5nCmhlbGxvV29ybGQ6Cglwcm90byAwIDEKCgkvLyB0ZXN0X2NvbnRyYWN0L3Rlc3QuYWxnby50czo1MgoJLy8gcmV0dXJuICdIZWxsbywgV29ybGQhJzsKCWJ5dGUgMHg0ODY1NmM2YzZmMmMyMDU3NmY3MjZjNjQyMSAvLyAiSGVsbG8sIFdvcmxkISIKCXJldHN1YgoKLy8gbWV0aG9kQXJnKGFwcGwpdWludDY0CiphYmlfcm91dGVfbWV0aG9kQXJnOgoJLy8gVGhlIEFCSSByZXR1cm4gcHJlZml4CglieXRlIDB4MTUxZjdjNzUKCgkvLyBjYWxsOiBhcHBsCgl0eG4gR3JvdXBJbmRleAoJaW50IDEKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBhcHBsCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBtZXRob2RBcmcoYXBwbCl1aW50NjQKCWNhbGxzdWIgbWV0aG9kQXJnCglpdG9iCgljb25jYXQKCWxvZwoJaW50IDEKCXJldHVybgoKLy8gbWV0aG9kQXJnKGNhbGw6IEFwcENhbGxUeG4pOiBBcHBJRAptZXRob2RBcmc6Cglwcm90byAxIDEKCgkvLyB0ZXN0X2NvbnRyYWN0L3Rlc3QuYWxnby50czo1NgoJLy8gcmV0dXJuIGNhbGwuYXBwbGljYXRpb25JRAoJZnJhbWVfZGlnIC0xIC8vIGNhbGw6IEFwcENhbGxUeG4KCWd0eG5zIEFwcGxpY2F0aW9uSUQKCXJldHN1YgoKLy8gbmVzdGVkVHhuQXJnKHBheSxhcHBsKXVpbnQ2NAoqYWJpX3JvdXRlX25lc3RlZFR4bkFyZzoKCS8vIFRoZSBBQkkgcmV0dXJuIHByZWZpeAoJYnl0ZSAweDE1MWY3Yzc1CgoJLy8gY2FsbDogYXBwbAoJdHhuIEdyb3VwSW5kZXgKCWludCAxCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgYXBwbAoJPT0KCWFzc2VydAoKCS8vIHR4bjogcGF5Cgl0eG4gR3JvdXBJbmRleAoJaW50IDIKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBwYXkKCT09Cglhc3NlcnQKCgkvLyBleGVjdXRlIG5lc3RlZFR4bkFyZyhwYXksYXBwbCl1aW50NjQKCWNhbGxzdWIgbmVzdGVkVHhuQXJnCglpdG9iCgljb25jYXQKCWxvZwoJaW50IDEKCXJldHVybgoKLy8gbmVzdGVkVHhuQXJnKHR4bjogUGF5VHhuLCBjYWxsOiBBcHBDYWxsVHhuKTogQXBwSUQKbmVzdGVkVHhuQXJnOgoJcHJvdG8gMiAxCgoJLy8gdGVzdF9jb250cmFjdC90ZXN0LmFsZ28udHM6NjAKCS8vIHJldHVybiBjYWxsLmFwcGxpY2F0aW9uSUQKCWZyYW1lX2RpZyAtMiAvLyBjYWxsOiBBcHBDYWxsVHhuCglndHhucyBBcHBsaWNhdGlvbklECglyZXRzdWIKCi8vIGRvdWJsZU5lc3RlZFR4bkFyZyhwYXksYXBwbCxwYXksYXBwbCl1aW50NjQKKmFiaV9yb3V0ZV9kb3VibGVOZXN0ZWRUeG5Bcmc6CgkvLyBUaGUgQUJJIHJldHVybiBwcmVmaXgKCWJ5dGUgMHgxNTFmN2M3NQoKCS8vIGNhbGwzOiBhcHBsCgl0eG4gR3JvdXBJbmRleAoJaW50IDEKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBhcHBsCgk9PQoJYXNzZXJ0CgoJLy8gdHhuMjogcGF5Cgl0eG4gR3JvdXBJbmRleAoJaW50IDIKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBwYXkKCT09Cglhc3NlcnQKCgkvLyBjYWxsMTogYXBwbAoJdHhuIEdyb3VwSW5kZXgKCWludCAzCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgYXBwbAoJPT0KCWFzc2VydAoKCS8vIHR4bjA6IHBheQoJdHhuIEdyb3VwSW5kZXgKCWludCA0CgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgcGF5Cgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBkb3VibGVOZXN0ZWRUeG5BcmcocGF5LGFwcGwscGF5LGFwcGwpdWludDY0CgljYWxsc3ViIGRvdWJsZU5lc3RlZFR4bkFyZwoJaXRvYgoJY29uY2F0Cglsb2cKCWludCAxCglyZXR1cm4KCi8vIGRvdWJsZU5lc3RlZFR4bkFyZyh0eG4wOiBQYXlUeG4sIGNhbGwxOiBBcHBDYWxsVHhuLCB0eG4yOiBQYXlUeG4sIGNhbGwzOiBBcHBDYWxsVHhuKTogQXBwSUQKZG91YmxlTmVzdGVkVHhuQXJnOgoJcHJvdG8gNCAxCgoJLy8gdGVzdF9jb250cmFjdC90ZXN0LmFsZ28udHM6NjQKCS8vIHJldHVybiBjYWxsMS5hcHBsaWNhdGlvbklECglmcmFtZV9kaWcgLTIgLy8gY2FsbDE6IEFwcENhbGxUeG4KCWd0eG5zIEFwcGxpY2F0aW9uSUQKCXJldHN1YgoKKmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCWludCAxCglyZXR1cm4KCipjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCAqYWJpX3JvdXRlX2NyZWF0ZUFwcGxpY2F0aW9uCgllcnIKCipjYWxsX05vT3A6CgltZXRob2QgImRvTWF0aCh1aW50NjQsdWludDY0LHN0cmluZyl1aW50NjQiCgltZXRob2QgInR4bkFyZyhwYXkpYWRkcmVzcyIKCW1ldGhvZCAiaGVsbG9Xb3JsZCgpc3RyaW5nIgoJbWV0aG9kICJtZXRob2RBcmcoYXBwbCl1aW50NjQiCgltZXRob2QgIm5lc3RlZFR4bkFyZyhwYXksYXBwbCl1aW50NjQiCgltZXRob2QgImRvdWJsZU5lc3RlZFR4bkFyZyhwYXksYXBwbCxwYXksYXBwbCl1aW50NjQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCAqYWJpX3JvdXRlX2RvTWF0aCAqYWJpX3JvdXRlX3R4bkFyZyAqYWJpX3JvdXRlX2hlbGxvV29ybGQgKmFiaV9yb3V0ZV9tZXRob2RBcmcgKmFiaV9yb3V0ZV9uZXN0ZWRUeG5BcmcgKmFiaV9yb3V0ZV9kb3VibGVOZXN0ZWRUeG5BcmcKCWVycg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEw" + }, + "contract": { + "name": "TestContract", + "desc": "", + "methods": [ + { + "name": "doMath", + "desc": "A method that takes two numbers and does either addition or subtraction", + "args": [ + { + "name": "a", + "type": "uint64", + "desc": "The first number" + }, + { + "name": "b", + "type": "uint64", + "desc": "The second number" + }, + { + "name": "operation", + "type": "string", + "desc": "The operation to perform. Can be either 'sum' or 'difference'" + } + ], + "returns": { + "type": "uint64", + "desc": "The result of the operation" + } + }, + { + "name": "txnArg", + "args": [ + { + "name": "txn", + "type": "pay" + } + ], + "returns": { + "type": "address" + } + }, + { + "name": "helloWorld", + "args": [], + "returns": { + "type": "string" + } + }, + { + "name": "methodArg", + "args": [ + { + "name": "call", + "type": "appl" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "nestedTxnArg", + "args": [ + { + "name": "txn", + "type": "pay" + }, + { + "name": "call", + "type": "appl" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "doubleNestedTxnArg", + "args": [ + { + "name": "txn0", + "type": "pay" + }, + { + "name": "call1", + "type": "appl" + }, + { + "name": "txn2", + "type": "pay" + }, + { + "name": "call3", + "type": "appl" + } + ], + "returns": { + "type": "uint64" + } + }, + { + "name": "createApplication", + "args": [], + "returns": { + "type": "void" + } + } + ] + } +} + +/** + * Defines an onCompletionAction of 'no_op' + */ +export type OnCompleteNoOp = { onCompleteAction?: 'no_op' | OnApplicationComplete.NoOpOC } +/** + * Defines an onCompletionAction of 'opt_in' + */ +export type OnCompleteOptIn = { onCompleteAction: 'opt_in' | OnApplicationComplete.OptInOC } +/** + * Defines an onCompletionAction of 'close_out' + */ +export type OnCompleteCloseOut = { onCompleteAction: 'close_out' | OnApplicationComplete.CloseOutOC } +/** + * Defines an onCompletionAction of 'delete_application' + */ +export type OnCompleteDelApp = { onCompleteAction: 'delete_application' | OnApplicationComplete.DeleteApplicationOC } +/** + * Defines an onCompletionAction of 'update_application' + */ +export type OnCompleteUpdApp = { onCompleteAction: 'update_application' | OnApplicationComplete.UpdateApplicationOC } +/** + * A state record containing a single unsigned integer + */ +export type IntegerState = { + /** + * Gets the state value as a BigInt. + */ + asBigInt(): bigint + /** + * Gets the state value as a number. + */ + asNumber(): number +} +/** + * A state record containing binary data + */ +export type BinaryState = { + /** + * Gets the state value as a Uint8Array + */ + asByteArray(): Uint8Array + /** + * Gets the state value as a string + */ + asString(): string +} + +export type AppCreateCallTransactionResult = AppCallTransactionResult & Partial & AppReference +export type AppUpdateCallTransactionResult = AppCallTransactionResult & Partial + +export type AppClientComposeCallCoreParams = Omit & { + sendParams?: Omit +} +export type AppClientComposeExecuteParams = Pick + +/** + * Defines the types of available calls and state of the TestContract smart contract. + */ +export type TestContract = { + /** + * Maps method signatures / names to their argument and return types. + */ + methods: + & Record<'doMath(uint64,uint64,string)uint64' | 'doMath', { + argsObj: { + /** + * The first number + */ + a: bigint | number + /** + * The second number + */ + b: bigint | number + /** + * The operation to perform. Can be either 'sum' or 'difference' + */ + operation: string + } + argsTuple: [a: bigint | number, b: bigint | number, operation: string] + /** + * The result of the operation + */ + returns: bigint + }> + & Record<'txnArg(pay)address' | 'txnArg', { + argsObj: { + txn: TransactionToSign | Transaction | Promise + } + argsTuple: [txn: TransactionToSign | Transaction | Promise] + returns: string + }> + & Record<'helloWorld()string' | 'helloWorld', { + argsObj: { + } + argsTuple: [] + returns: string + }> + & Record<'methodArg(appl)uint64' | 'methodArg', { + argsObj: { + call: TransactionToSign | Transaction | Promise + } + argsTuple: [call: TransactionToSign | Transaction | Promise] + returns: bigint + }> + & Record<'nestedTxnArg(pay,appl)uint64' | 'nestedTxnArg', { + argsObj: { + txn: TransactionToSign | Transaction | Promise + call: TransactionToSign | Transaction | Promise + } + argsTuple: [txn: TransactionToSign | Transaction | Promise, call: TransactionToSign | Transaction | Promise] + returns: bigint + }> + & Record<'doubleNestedTxnArg(pay,appl,pay,appl)uint64' | 'doubleNestedTxnArg', { + argsObj: { + txn0: TransactionToSign | Transaction | Promise + call1: TransactionToSign | Transaction | Promise + txn2: TransactionToSign | Transaction | Promise + call3: TransactionToSign | Transaction | Promise + } + argsTuple: [txn0: TransactionToSign | Transaction | Promise, call1: TransactionToSign | Transaction | Promise, txn2: TransactionToSign | Transaction | Promise, call3: TransactionToSign | Transaction | Promise] + returns: bigint + }> + & Record<'createApplication()void' | 'createApplication', { + argsObj: { + } + argsTuple: [] + returns: void + }> +} +/** + * Defines the possible abi call signatures + */ +export type TestContractSig = keyof TestContract['methods'] +/** + * Defines an object containing all relevant parameters for a single call to the contract. Where TSignature is undefined, a bare call is made + */ +export type TypedCallParams = { + method: TSignature + methodArgs: TSignature extends undefined ? undefined : Array +} & AppClientCallCoreParams & CoreAppCallArgs +/** + * Defines the arguments required for a bare call + */ +export type BareCallArgs = Omit +/** + * Maps a method signature from the TestContract smart contract to the method's arguments in either tuple of struct form + */ +export type MethodArgs = TestContract['methods'][TSignature]['argsObj' | 'argsTuple'] +/** + * Maps a method signature from the TestContract smart contract to the method's return type + */ +export type MethodReturn = TestContract['methods'][TSignature]['returns'] + +/** + * A factory for available 'create' calls + */ +export type TestContractCreateCalls = (typeof TestContractCallFactory)['create'] +/** + * Defines supported create methods for this smart contract + */ +export type TestContractCreateCallParams = + | (TypedCallParams<'createApplication()void'> & (OnCompleteNoOp)) +/** + * Defines arguments required for the deploy method. + */ +export type TestContractDeployArgs = { + deployTimeParams?: TealTemplateParams + /** + * A delegate which takes a create call factory and returns the create call params for this smart contract + */ + createCall?: (callFactory: TestContractCreateCalls) => TestContractCreateCallParams +} + + +/** + * Exposes methods for constructing all available smart contract calls + */ +export abstract class TestContractCallFactory { + /** + * Gets available create call factories + */ + static get create() { + return { + /** + * Constructs a create call for the TestContract smart contract using the createApplication()void ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + createApplication(args: MethodArgs<'createApplication()void'>, params: AppClientCallCoreParams & CoreAppCallArgs & AppClientCompilationParams & (OnCompleteNoOp) = {}) { + return { + method: 'createApplication()void' as const, + methodArgs: Array.isArray(args) ? args : [], + ...params, + } + }, + } + } + + /** + * Constructs a no op call for the doMath(uint64,uint64,string)uint64 ABI method + * + * A method that takes two numbers and does either addition or subtraction + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static doMath(args: MethodArgs<'doMath(uint64,uint64,string)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'doMath(uint64,uint64,string)uint64' as const, + methodArgs: Array.isArray(args) ? args : [args.a, args.b, args.operation], + ...params, + } + } + /** + * Constructs a no op call for the txnArg(pay)address ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static txnArg(args: MethodArgs<'txnArg(pay)address'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'txnArg(pay)address' as const, + methodArgs: Array.isArray(args) ? args : [args.txn], + ...params, + } + } + /** + * Constructs a no op call for the helloWorld()string ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static helloWorld(args: MethodArgs<'helloWorld()string'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'helloWorld()string' as const, + methodArgs: Array.isArray(args) ? args : [], + ...params, + } + } + /** + * Constructs a no op call for the methodArg(appl)uint64 ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static methodArg(args: MethodArgs<'methodArg(appl)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'methodArg(appl)uint64' as const, + methodArgs: Array.isArray(args) ? args : [args.call], + ...params, + } + } + /** + * Constructs a no op call for the nestedTxnArg(pay,appl)uint64 ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static nestedTxnArg(args: MethodArgs<'nestedTxnArg(pay,appl)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'nestedTxnArg(pay,appl)uint64' as const, + methodArgs: Array.isArray(args) ? args : [args.txn, args.call], + ...params, + } + } + /** + * Constructs a no op call for the doubleNestedTxnArg(pay,appl,pay,appl)uint64 ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static doubleNestedTxnArg(args: MethodArgs<'doubleNestedTxnArg(pay,appl,pay,appl)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'doubleNestedTxnArg(pay,appl,pay,appl)uint64' as const, + methodArgs: Array.isArray(args) ? args : [args.txn0, args.call1, args.txn2, args.call3], + ...params, + } + } +} + +/** + * A client to make calls to the TestContract smart contract + */ +export class TestContractClient { + /** + * The underlying `ApplicationClient` for when you want to have more flexibility + */ + public readonly appClient: ApplicationClient + + private readonly sender: SendTransactionFrom | undefined + + /** + * Creates a new instance of `TestContractClient` + * + * @param appDetails appDetails The details to identify the app to deploy + * @param algod An algod client instance + */ + constructor(appDetails: AppDetails, private algod: Algodv2) { + this.sender = appDetails.sender + this.appClient = algokit.getAppClient({ + ...appDetails, + app: APP_SPEC + }, algod) + } + + /** + * Checks for decode errors on the AppCallTransactionResult and maps the return value to the specified generic type + * + * @param result The AppCallTransactionResult to be mapped + * @param returnValueFormatter An optional delegate to format the return value if required + * @returns The smart contract response with an updated return value + */ + protected mapReturnValue(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType & TResult { + if(result.return?.decodeError) { + throw result.return.decodeError + } + const returnValue = result.return?.returnValue !== undefined && returnValueFormatter !== undefined + ? returnValueFormatter(result.return.returnValue) + : result.return?.returnValue as TReturn | undefined + return { ...result, return: returnValue } as AppCallTransactionResultOfType & TResult + } + + /** + * Calls the ABI method with the matching signature using an onCompletion code of NO_OP + * + * @param typedCallParams An object containing the method signature, args, and any other relevant parameters + * @param returnValueFormatter An optional delegate which when provided will be used to map non-undefined return values to the target type + * @returns The result of the smart contract call + */ + public async call(typedCallParams: TypedCallParams, returnValueFormatter?: (value: any) => MethodReturn) { + return this.mapReturnValue>(await this.appClient.call(typedCallParams), returnValueFormatter) + } + + /** + * Idempotently deploys the TestContract smart contract. + * + * @param params The arguments for the contract calls and any additional parameters for the call + * @returns The deployment result + */ + public deploy(params: TestContractDeployArgs & AppClientDeployCoreParams = {}): ReturnType { + const createArgs = params.createCall?.(TestContractCallFactory.create) + return this.appClient.deploy({ + ...params, + createArgs, + createOnCompleteAction: createArgs?.onCompleteAction, + }) + } + + /** + * Gets available create methods + */ + public get create() { + const $this = this + return { + /** + * Creates a new instance of the TestContract smart contract using the createApplication()void ABI method. + * + * @param args The arguments for the smart contract call + * @param params Any additional parameters for the call + * @returns The create result + */ + async createApplication(args: MethodArgs<'createApplication()void'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}) { + return $this.mapReturnValue, AppCreateCallTransactionResult>(await $this.appClient.create(TestContractCallFactory.create.createApplication(args, params))) + }, + } + } + + /** + * Makes a clear_state call to an existing instance of the TestContract smart contract. + * + * @param args The arguments for the bare call + * @returns The clear_state result + */ + public clearState(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.appClient.clearState(args) + } + + /** + * Calls the doMath(uint64,uint64,string)uint64 ABI method. + * + * A method that takes two numbers and does either addition or subtraction + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call: The result of the operation + */ + public doMath(args: MethodArgs<'doMath(uint64,uint64,string)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(TestContractCallFactory.doMath(args, params)) + } + + /** + * Calls the txnArg(pay)address ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public txnArg(args: MethodArgs<'txnArg(pay)address'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(TestContractCallFactory.txnArg(args, params)) + } + + /** + * Calls the helloWorld()string ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public helloWorld(args: MethodArgs<'helloWorld()string'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(TestContractCallFactory.helloWorld(args, params)) + } + + /** + * Calls the methodArg(appl)uint64 ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public methodArg(args: MethodArgs<'methodArg(appl)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(TestContractCallFactory.methodArg(args, params)) + } + + /** + * Calls the nestedTxnArg(pay,appl)uint64 ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public nestedTxnArg(args: MethodArgs<'nestedTxnArg(pay,appl)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(TestContractCallFactory.nestedTxnArg(args, params)) + } + + /** + * Calls the doubleNestedTxnArg(pay,appl,pay,appl)uint64 ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public doubleNestedTxnArg(args: MethodArgs<'doubleNestedTxnArg(pay,appl,pay,appl)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(TestContractCallFactory.doubleNestedTxnArg(args, params)) + } + + public compose(): TestContractComposer { + const client = this + const atc = new AtomicTransactionComposer() + let promiseChain:Promise = Promise.resolve() + const resultMappers: Array any)> = [] + return { + doMath(args: MethodArgs<'doMath(uint64,uint64,string)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.doMath(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + txnArg(args: MethodArgs<'txnArg(pay)address'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.txnArg(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + helloWorld(args: MethodArgs<'helloWorld()string'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.helloWorld(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + methodArg(args: MethodArgs<'methodArg(appl)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.methodArg(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + nestedTxnArg(args: MethodArgs<'nestedTxnArg(pay,appl)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.nestedTxnArg(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + doubleNestedTxnArg(args: MethodArgs<'doubleNestedTxnArg(pay,appl,pay,appl)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.doubleNestedTxnArg(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + clearState(args?: BareCallArgs & AppClientComposeCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.clearState({...args, sendParams: {...args?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + addTransaction(txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, defaultSender?: SendTransactionFrom) { + promiseChain = promiseChain.then(async () => atc.addTransaction(await algokit.getTransactionWithSigner(txn, defaultSender ?? client.sender))) + return this + }, + async atc() { + await promiseChain + return atc + }, + async simulate(options?: SimulateOptions) { + await promiseChain + const result = await atc.simulate(client.algod, new modelsv2.SimulateRequest({ txnGroups: [], ...options })) + return { + ...result, + returns: result.methodResults?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue) + } + }, + async execute(sendParams?: AppClientComposeExecuteParams) { + await promiseChain + const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams }, client.algod) + return { + ...result, + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue) + } + } + } as unknown as TestContractComposer + } +} +export type TestContractComposer = { + /** + * Calls the doMath(uint64,uint64,string)uint64 ABI method. + * + * A method that takes two numbers and does either addition or subtraction + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + doMath(args: MethodArgs<'doMath(uint64,uint64,string)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, MethodReturn<'doMath(uint64,uint64,string)uint64'>]> + + /** + * Calls the txnArg(pay)address ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + txnArg(args: MethodArgs<'txnArg(pay)address'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, MethodReturn<'txnArg(pay)address'>]> + + /** + * Calls the helloWorld()string ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + helloWorld(args: MethodArgs<'helloWorld()string'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, MethodReturn<'helloWorld()string'>]> + + /** + * Calls the methodArg(appl)uint64 ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + methodArg(args: MethodArgs<'methodArg(appl)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, MethodReturn<'methodArg(appl)uint64'>]> + + /** + * Calls the nestedTxnArg(pay,appl)uint64 ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + nestedTxnArg(args: MethodArgs<'nestedTxnArg(pay,appl)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, MethodReturn<'nestedTxnArg(pay,appl)uint64'>]> + + /** + * Calls the doubleNestedTxnArg(pay,appl,pay,appl)uint64 ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + doubleNestedTxnArg(args: MethodArgs<'doubleNestedTxnArg(pay,appl,pay,appl)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, MethodReturn<'doubleNestedTxnArg(pay,appl,pay,appl)uint64'>]> + + /** + * Makes a clear_state call to an existing instance of the TestContract smart contract. + * + * @param args The arguments for the bare call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + clearState(args?: BareCallArgs & AppClientComposeCallCoreParams & CoreAppCallArgs): TestContractComposer<[...TReturns, undefined]> + + /** + * Adds a transaction to the composer + * + * @param txn One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by one of algokit utils helpers (signer is obtained from the defaultSender parameter) + * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not include a signer. + */ + addTransaction(txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, defaultSender?: SendTransactionFrom): TestContractComposer + /** + * Returns the underlying AtomicTransactionComposer instance + */ + atc(): Promise + /** + * Simulates the transaction group and returns the result + */ + simulate(options?: SimulateOptions): Promise> + /** + * Executes the transaction group and returns the results + */ + execute(sendParams?: AppClientComposeExecuteParams): Promise> +} +export type SimulateOptions = Omit[0], 'txnGroups'> +export type TestContractComposerSimulateResult = { + returns: TReturns + methodResults: ABIResult[] + simulateResponse: modelsv2.SimulateResponse +} +export type TestContractComposerResults = { + returns: TReturns + groupId: string + txIds: string[] + transactions: Transaction[] +}