Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/app-client-deprecation' into fea…
Browse files Browse the repository at this point in the history
…t/puya-debugging
  • Loading branch information
aorumbayev committed Sep 13, 2024
2 parents 15328db + b95895f commit 2c0a8d3
Show file tree
Hide file tree
Showing 136 changed files with 9,124 additions and 2,020 deletions.
14 changes: 8 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ To use this library simply include the following at the top of your file:
import { AlgorandClient, Config } from '@algorandfoundation/algokit-utils'
```

As well as `AlgorandClient` and `Config`, you can use intellisense to auto-complete the various types that you can import withing the {} in your favourite Integrated Development Environment (IDE), or you can refer to the [reference documentation](./code/modules/index.md).
As well as `AlgorandClient` and `Config`, you can use intellisense to auto-complete the various types that you can import within the `{}` in your favourite Integrated Development Environment (IDE), or you can refer to the [reference documentation](./code/modules/index.md).

> [!WARNING]
> Previous versions of AlgoKit Utils encouraged you to include an import that looks like this (note the subtle difference of the extra `* as algokit`):
Expand All @@ -45,7 +45,9 @@ As well as `AlgorandClient` and `Config`, you can use intellisense to auto-compl
> import * as algokit from '@algorandfoundation/algokit-utils'
> ```
>
> This version will still work, but it exposes an older, function-based interface to the functionality that is in the process of being deprecated. The recommended way to use AlgoKit Utils is via the `AlgorandClient` class mentioned below, which is easier and more convenient to use. Some functionality won't yet be migrated to the new approach and this old approach will be needed, but the documentation pages will indicate when this is the case.
> This version will still work until the next major version bump, but it exposes an older, function-based interface to the functionality that is deprecated. The new way to use AlgoKit Utils is via the `AlgorandClient` class, which is easier, simpler and more convenient to use and has powerful new features.
>
> If you are migrating from the old functions to the new ones then you can follow the [migration guide](v7-migration.md).
The main entrypoint to the bulk of the functionality is the `AlgorandClient` class, most of the time you can get started by typing `AlgorandClient.` and choosing one of the static initialisation methods to create an [Algorand client](./capabilities/algorand-client.md), e.g.:
Expand Down Expand Up @@ -138,15 +140,15 @@ To turn on debug mode you can use the following:
Config.configure({ debug: true })
```
To retrieve the current debug state you can use [`algokit.Config.debug`](./code/interfaces/types_config.Config.md).
To retrieve the current debug state you can use [`Config.debug`](./code/interfaces/types_config.Config.md).
This will turn on things like automatic tracing, more verbose logging and [advanced debugging](./capabilities/debugging.md). It's likely this option will result in extra HTTP calls to algod so worth being careful when it's turned on.
If you want to temporarily turn it on you can use the [`withDebug`](./code/classes/types_config.UpdatableConfig.md#withdebug) function:
```typescript
Config.withDebug(() => {
// Do stuff with algokit.Config.debug set to true
// Do stuff with Config.debug set to true
})
```
Expand All @@ -159,11 +161,11 @@ The library helps you interact with and develop against the Algorand blockchain
- [**Client management**](./capabilities/client.md) - Creation of (auto-retry) algod, indexer and kmd clients against various networks resolved from environment or specified configuration, and creation of other API clients (e.g. TestNet Dispenser API and app clients)
- [**Account management**](./capabilities/account.md) - Creation, use, and management of accounts including mnemonic, rekeyed, multisig, transaction signer ([useWallet](https://github.com/TxnLab/use-wallet) for dApps and Atomic Transaction Composer compatible signers), idempotent KMD accounts and environment variable injected
- [**Algo amount handling**](./capabilities/amount.md) - Reliable, explicit, and terse specification of microAlgo and Algo amounts and safe conversion between them
- [**Transaction management**](./capabilities/transaction.md) - Ability to construct and send single and atomically grouped transactions with consistent and highly configurable semantics, including configurable control of transaction notes, logging, fees, validity, signing, and sending behaviour
- [**Transaction management**](./capabilities/transaction.md) - Ability to construct, simulate and send transactions with consistent and highly configurable semantics, including configurable control of transaction notes, logging, fees, validity, signing, and sending behaviour
- **Higher-order use cases**
- [**Asset management**](./capabilities/asset.md) - Creation, transfer, destroying, opting in and out and managing Algorand Standard Assets
- [**Typed application clients**](./capabilities/typed-app-clients.md) - Type-safe application clients that are [generated](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md#1-typed-clients) from ARC-0032 application spec files and allow you to intuitively and productively interact with a deployed app, which is the recommended way of interacting with apps and builds on top of the following capabilities:
- [**ARC-0032 Application Spec client**](./capabilities/app-client.md) - Builds on top of the App management and App deployment capabilities (below) to provide a high productivity application client that works with ARC-0032 application spec defined smart contracts
- [**ARC-56 / ARC-32 App client and App factory**](./capabilities/app-client.md) - Builds on top of the App management and App deployment capabilities (below) to provide a high productivity application client that works with ARC-56 and ARC-32 application spec defined smart contracts
- [**App management**](./capabilities/app.md) - Creation, updating, deleting, calling (ABI and otherwise) smart contract apps and the metadata associated with them (including state and boxes)
- [**App deployment**](./capabilities/app-deploy.md) - Idempotent (safely retryable) deployment of an app, including deploy-time immutability and permanence control and TEAL template substitution
- [**Algo transfers (payments)**](./capabilities/transfer.md) - Ability to easily initiate Algo transfers between accounts, including dispenser management and idempotent account funding
Expand Down
52 changes: 37 additions & 15 deletions docs/capabilities/account.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,41 @@ const accountManager = new AccountManager(clientManager)

The core internal type that holds information about a signer/sender pair for a transaction is [`TransactionSignerAccount`](../code/interfaces/types_account.TransactionSignerAccount.md), which represents an `algosdk.TransactionSigner` (`signer`) along with a sender address (`addr`) as the encoded string address.

Many methods in `AccountManager` expose a `TransactionSignerAccount`.
Many methods in `AccountManager` expose a `TransactionSignerAccount`. `TransactionSignerAccount` can be used with `AtomicTransactionComposer`, [`AlgoKitComposer`](./algokit-composer.md) and [useWallet](https://github.com/TxnLab/use-wallet).

### `SendTransactionFrom`
## Registering a signer

> [!NOTE]
> The [legacy functions](../README.md#usage) within AlgoKit Utils make use of a [`SendTransactionFrom`](../code/modules/types_transaction.md#sendtransactionfrom) union type that is slowly being phased out in favour of the simpler `TransactionSignerAccount`. This `SendTransactionFrom` type is still prevalent within the legacy functions though.
The `AccountManager` keeps track of which signer is associated with a given sender address. This is used by [`AlgorandClient`](./algorand-client.md) to automatically sign transactions by that sender. Any of the [methods](#accounts) within `AccountManager` that return an account will automatically register the signer with the sender. If however, you are creating a signer external to the `AccountManager`, for instance when using the use-wallet library in a dApp, then you need to register the signer with the `AccountManager` if you want it to be able to automatically sign transactions from that sender.

`SendTransactionFrom` is a union of the following types that each represent an account that can both sign a transaction and represent a sender address:
There are two methods that can be used for this, `setSignerFromAccount`, which takes any number of [account based objects](#underlying-account-classes) that combine signer and sender (`TransactionSignerAccount` | `algosdk.Account` | `algosdk.LogicSigAccount` | `SigningAccount` | `MultisigAccount`), or `setSigner` which takes the sender address and the `TransactionSigner`:

- `Account` - An in-built algosdk `Account` object
- [`SigningAccount`](../code/classes/types_account.SigningAccount.md) - An abstraction around `algosdk.Account` that supports rekeyed accounts
- `LogicSigAccount` - An in-built algosdk `algosdk.LogicSigAccount` object
- [`MultisigAccount`](../code/classes/types_account.MultisigAccount.md) - An abstraction around `algosdk.MultisigMetadata`, `algosdk.makeMultiSigAccountTransactionSigner`, `algosdk.multisigAddress`, `algosdk.signMultisigTransaction` and `algosdk.appendSignMultisigTransaction` that supports multisig accounts with one or more signers present
- [`TransactionSignerAccount`](../code/interfaces/types_account.TransactionSignerAccount.md) - An interface that provides a sender address alongside a transaction signer (e.g. for use with `AtomicTransactionComposer` or [useWallet](https://github.com/TxnLab/use-wallet))
```typescript
algorand.account
.setSignerFromAccount(algosdk.generateAccount())
.setSignerFromAccount(new algosdk.LogicSigAccount(program, args))
.setSignerFromAccount(new SigningAccount(mnemonic, sender))
.setSignerFromAccount(new MultisigAccount({ version: 1, threshold: 1, addrs: ['ADDRESS1...', 'ADDRESS2...'] }, [account1, account2]))
.setSignerFromAccount({ addr: 'SENDERADDRESS', signer: transactionSigner })
.setSigner('SENDERADDRESS', transactionSigner)
```

The use of in-built algosdk types like `Account`, `LogicSigAccount` and `TransactionSigner` is aligned to the [Modularity](../README.md#core-principles) principle. Allowing you to co-exist non AlgoKit Utils code with AlgoKit Utils functions.
## Default signer

AlgoKit Utils provides a few helper methods to take one of these `SendTransactionFrom` objects (that to reiterate uses the [legacy imports](../README.md#usage) to access):
If you want to have a default signer that is used to sign transactions without a registered signer (rather than throwing an exception) then you can [register a default signer](../code/classes/types_account_manager.AccountManager.md#setdefaultsigner):

- [`algokit.getSenderAddress`](../code/modules/index.md#getsenderaddress) - Returns the public address of the sender the account represents
- [`algokit.getSenderTransactionSigner`](../code/modules/index.md#getsendertransactionsigner) - Returns a `TransactionSigner` to represent the signer of the account' note: this is memoized so multiple calls to this for the same account will safely return the same `TransactionSigner` instance; this works nicely with `AtomicTransactionComposer`
- [`algokit.signTransaction`](../code/modules/index.md#signtransaction) - Signs a single `algosdk.Transaction` object with the given account
```typescript
algorand.account.setDefaultSigner(myDefaultSigner)
```

## Get a signer

[`AlgorandClient`](./algorand-client.md) will automatically retrieve a signer when signing a transaction, but if you need to get a `TransactionSigner` externally to do something more custom then you can [retrieve the signer](../code/classes//types_account_manager.AccountManager.md#getsigner) for a given sender address:

```typescript
const signer = algorand.account.getSigner('SENDER_ADDRESS')
```

If there is no signer registered for that sender address it will either return the default signer ([if registered](#default-signer)) or throw an exception.

## Accounts

Expand All @@ -55,6 +68,15 @@ In order to get/register accounts for signing operations you can use the followi
- [`algorand.account.fromKmd()`](../code/classes/types_account_manager.AccountManager.md#fromkmd) - Returns an account with private key loaded from the given KMD wallet (identified by name)
- [`algorand.account.logicsig(program, args?)`](../code/classes/types_account_manager.AccountManager.md#logicsig) - Returns an account that represents a logic signature

### Underlying account classes

While `TransactionSignerAccount` is the main class used to represent an account that can sign, there are underlying account classes that can underpin the signer within the transaction signer account.

- `Account` - An in-built `algosdk.Account` object that has an address and private signing key, this can be created
- [`SigningAccount`](../code/classes/types_account.SigningAccount.md) - An abstraction around `algosdk.Account` that supports rekeyed accounts
- `LogicSigAccount` - An in-built algosdk `algosdk.LogicSigAccount` object
- [`MultisigAccount`](../code/classes/types_account.MultisigAccount.md) - An abstraction around `algosdk.MultisigMetadata`, `algosdk.makeMultiSigAccountTransactionSigner`, `algosdk.multisigAddress`, `algosdk.signMultisigTransaction` and `algosdk.appendSignMultisigTransaction` that supports multisig accounts with one or more signers present

### Dispenser

- [`algorand.account.dispenserFromEnvironment()`](../code/classes/types_account_manager.AccountManager.md#dispenserfromenvironment) - Returns an account (with private key loaded) that can act as a dispenser from environment variables, or against default LocalNet if no environment variables present
Expand Down
6 changes: 4 additions & 2 deletions docs/capabilities/algorand-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ The signature for the calls to send a single transaction usually look like:
- To get intellisense on the params, open an object parenthesis (`{`) and use your IDE's intellisense keyboard shortcut (e.g. ctrl+space).
- `{ComposerTransactionTypeParams}` will be the parameters that are specific to that transaction type e.g. `PaymentParams`, [see the full list](../code/modules/types_composer.md#type-aliases)
- [`CommonTransactionParams`](../code/modules/types_composer.md#commontransactionparams) are the [common transaction parameters](#transaction-parameters) that can be specified for every single transaction
- [`ExecuteParams`](../code/interfaces/types_composer.ExecuteParams.md) are the [parameters](#transaction-parameters) that control execution semantics when sending transactions to the network
- [`ExecuteParams`](../code/interfaces/types_transaction.ExecuteParams.md) are the [parameters](#transaction-parameters) that control execution semantics when sending transactions to the network
- [`SendSingleTransactionResult`](../code/modules/types_algorand_client.md#sendsingletransactionresult) is all of the information that is relevant when [sending a single transaction to the network](./transaction.md#sending-a-transaction)

Generally, the functions to immediately send a single transaction will emit log messages before and/or after sending the transaction. You can opt-out of this by sending `suppressLog: true`.
Expand Down Expand Up @@ -121,10 +121,12 @@ There are two common base interfaces that get reused:
- `validityWindow?: number` - How many rounds the transaction should be valid for, if not specified then the registered default validity window will be used.
- `firstValidRound?: bigint` - Set the first round this transaction is valid. If left undefined, the value from algod will be used. We recommend you 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.
- [`ExecuteParams`](../code/interfaces/types_composer.ExecuteParams.md)
- [`ExecuteParams`](../code/interfaces/types_transaction.ExecuteParams.md)
- `maxRoundsToWaitForConfirmation?: number` - The number of rounds to wait for confirmation. By default until the latest lastValid has past.
- `suppressLog?: boolean` - Whether to suppress log messages from transaction send, default: do not suppress.

Then on top of that the base type gets extended for the specific type of transaction you are issuing. These are all defined as part of [`AlgoKitComposer`](./algokit-composer.md).

### Transaction configuration

AlgorandClient caches network provided transaction values for you automatically to reduce network traffic. It has a set of default configurations that control this behaviour, but you have the ability to override and change the configuration of this behaviour:
Expand Down
6 changes: 3 additions & 3 deletions docs/capabilities/amount.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ To import the AlgoAmount class you can access it via:
import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount'
```

You may not need to import this type to use it though since there are also special methods that are exposed from `algokit.` and extend the `number` protoype per below.
You may not need to import this type to use it though since there are also special methods that are exposed from the root AlgoKit Utils export and also others that extend the `number` protoype per below.

### Creating an `AlgoAmount`

Expand All @@ -25,12 +25,12 @@ There are a few ways to create an `AlgoAmount`:
- Algo
- Constructor: `new AlgoAmount({algo: 10})`
- Static helper: `AlgoAmount.algo(10)`
- AlgoKit Helper: `algokit.algo(10)`
- AlgoKit Helper: `algo(10)`
- Number coersion: `(10).algo()` (note: you have to wrap the number in brackets or have it in a variable or function return, a raw number value can't have a method called on it)
- microAlgo
- Constructor: `new AlgoAmount({microAlgos: 10_000})`
- Static helper: `AlgoAmount.algo(10)`
- AlgoKit Helper: `algokit.microAlgo(10_000)`
- AlgoKit Helper: `microAlgo(10_000)`
- Number coersion: `(10_000).microAlgo()` (note: you have to wrap the number in brackets or have it in a variable or function return, a raw number value can't have a method called on it)

Note: per above, to use any of the versions that reference `AlgoAmount` type itself you need to import it:
Expand Down
Loading

0 comments on commit 2c0a8d3

Please sign in to comment.