Account Management
Account management is one of the core capabilities provided by AlgoKit Utils. It allows you to create mnemonic, rekeyed, multisig, transaction signer, idempotent KMD and environment variable injected accounts that can be used to sign transactions as well as representing a sender address at the same time. This significantly simplifies management of transaction signing.
Account Manager Object
The AccountManager is a class that is used to get, create, and fund accounts and perform account-related actions such as funding. The AccountManager also keeps track of signers for each address so when using the AlgokitComposer to send transactions, a signer function does not need to manually be specified for each transaction - instead it can be inferred from the sender address automatically!
To get an instance of AccountManager, you can use either AlgorandClient via algorand.account or instantiate it directly (passing in a ClientManager):
import { AccountManager } from '@algorandfoundation/algokit-utils/types/account-manager';const accountManager = new AccountManager(clientManager);Transaction Signer Account
The core internal type that holds information about a signer/sender pair for a transaction is TransactionSignerAccount, which represents an algosdk.TransactionSigner (signer) along with a sender address (addr) as the encoded string address.
Many methods in AccountManager expose a TransactionSignerAccount.
SendTransactionFrom
SendTransactionFrom is a union of the following types that each represent an account that can both sign a transaction and represent a sender address:
- Account- An in-built algosdk- Accountobject
- SigningAccount- An abstraction around- algosdk.Accountthat supports rekeyed accounts
- LogicSigAccount- An in-built algosdk- algosdk.LogicSigAccountobject
- MultisigAccount- An abstraction around- algosdk.MultisigMetadata,- algosdk.makeMultiSigAccountTransactionSigner,- algosdk.multisigAddress,- algosdk.signMultisigTransactionand- algosdk.appendSignMultisigTransactionthat supports multisig accounts with one or more signers present
- TransactionSignerAccount- An interface that provides a sender address alongside a transaction signer (e.g. for use with- AtomicTransactionComposeror useWallet)
The use of in-built algosdk types like Account, LogicSigAccount and TransactionSigner is aligned to the Modularity principle. Allowing you to co-exist non AlgoKit Utils code with AlgoKit Utils functions.
AlgoKit Utils provides a few helper methods to take one of these SendTransactionFrom objects (that to reiterate uses the legacy imports to access):
- algokit.getSenderAddress- Returns the public address of the sender the account represents
- algokit.getSenderTransactionSigner- Returns a- TransactionSignerto represent the signer of the account’ note: this is memoized so multiple calls to this for the same account will safely return the same- TransactionSignerinstance; this works nicely with- AtomicTransactionComposer
- algokit.signTransaction- Signs a single- algosdk.Transactionobject with the given account
Accounts
In order to get/register accounts for signing operations you can use the following methods on AccountManager (expressed here as algorand.account to denote the syntax via an AlgorandClient):
- algorand.account.fromEnvironment(name, fundWith)- Registers and returns an account with private key loaded by convention based on the given name identifier - either by idempotently creating the account in KMD or from environment variable via- process.env['{NAME}_MNEMONIC']and (optionally)- process.env['{NAME}_SENDER'](if account is rekeyed)- This allows you to have powerful code that will automatically create and fund an account by name locally and when deployed against TestNet/MainNet will automatically resolve from environment variables, without having to have different code
- Note: fundWithallows you to control how many ALGOs are seeded into an account created in KMD
 
- algorand.account.fromMnemonic(mnemonicSecret, sender?)- Registers and returns an account with secret key loaded by taking the mnemonic secret
- algorand.account.multisig(multisigParams, signingAccounts)- Registers and returns a multisig account with one or more signing keys loaded
- algorand.account.rekeyed(signer, sender)- Registers and returns an account representing the given rekeyed sender/signer combination
- algorand.account.random()- Returns a new, cryptographically randomly generated account with private key loaded
- algorand.account.fromKmd()- Returns an account with private key loaded from the given KMD wallet (identified by name)
- algorand.account.logicsig(program, args?)- Returns an account that represents a logic signature
Dispenser
- algorand.account.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
- algorand.account.localNetDispenser()- Returns an account with private key loaded that can act as a dispenser for the default LocalNet dispenser account
Rekey account
One of the unique features of Algorand is the ability to change the private key that can authorise transactions for an account. This is called rekeying.
You can issue a transaction to rekey an account by using the algokit.rekeyAccount(rekey, algod) function. The rekey parameter is an AlgoRekeyParams object with the following properties:
- 
All properties in SendTransactionParams
- 
from: SendTransactionFrom- The account that will be rekeyed
- 
rekeyTo: SendTransactionFrom | string- The address of the account that will be used to authorise transactions for the rekeyed account going forward
- 
transactionParams?: SuggestedParams- The optional transaction parameters
- 
note?: TransactionNote- The transaction note
- 
lease?: string | Uint8Array: A lease to assign to the transaction to enforce a mutually exclusive transaction (useful to prevent double-posting and other scenarios)
1// Example2await algokit.rekeyAccount(3  {4    from: account,5    rekeyTo: newAccount,6    // Optionally specify transactionParams, note, lease and transaction sending parameters7  },8  algod,9);10
11const rekeyedAccount = algokit.rekeyedAccount(newAccount, account.addr);12// rekeyedAccount can be used to sign transactions on behalf of account...KMD account management
When running LocalNet, you have an instance of the Key Management Daemon, which is useful for:
- Accessing the private key of the default accounts that are pre-seeded with algos so that other accounts can be funded and it’s possible to use LocalNet
- Idempotently creating new accounts against a name that will stay intact while the LocalNet instance is running without you needing to store private keys anywhere (i.e. completely automated)
The KMD SDK is fairly low level so to make use of it there is a fair bit of boilerplate code that’s needed. This code has been abstracted away into the KmdAccountManager class.
To get an instance of the KmdAccountManager class you can access it from AlgorandClient via algorand.account.kmd or instantiate it directly (passing in a ClientManager):
1import { KmdAccountManager } from '@algorandfoundation/algokit-utils/types/kmd-account-manager';2
3// Algod client only4const kmdAccountManager = new KmdAccountManager(clientManager);The methods that are available are:
- getWalletAccount(walletName, predicate?, sender?)- Returns an Algorand signing account with private key loaded from the given KMD wallet (identified by name).
- getOrCreateWalletAccount(name, fundWith?)- Gets an account with private key loaded from a KMD wallet of the given name, or alternatively creates one with funds in it via a KMD wallet of the given name.
- getLocalNetDispenserAccount()- Returns an Algorand account with private key loaded for the default LocalNet dispenser account (that can be used to fund other accounts)
1// Get a wallet account that seeded the LocalNet network2const defaultDispenserAccount = await kmdAccountManager.getWalletAccount(3    'unencrypted-default-wallet',4    (a) => a.status !== 'Offline' && a.amount > 1_000_000_000,5  )6  // Same as above, but dedicated method call for convenience7  const localNetDispenserAccount = await kmdAccountManager.getLocalNetDispenserAccount()8  // Idempotently get (if exists) or create (if it doesn't exist yet) an account by name using KMD9  // if creating it then fund it with 2 Algos from the default dispenser account10  const newAccount = await kmdAccountManager.getOrCreateWalletAccount('account1', (2).algos())11  // This will return the same account as above since the name matches12  const existingAccount = await kmdAccountManager.getOrCreateWalletAccount('account1')Some of this functionality is directly exposed from AccountManager, which has the added benefit of registering the account as a signer so they can be automatically used to sign transactions when using via AlgorandClient:
const localNetDispenser = await algorand.account.localNetDispenser(); // Get and register LocalNet dispenserconst dispenser = await algorand.account.dispenserFromEnvironment(); // Get and register a dispenser by environment variable, or if not set then LocalNet dispenser via KMDconst account1 = await algorand.account.fromKmd('account1', (2).algos()); // Get / create and register account from KMD idempotently by name