App
App management¶
App management is a higher-order use case capability provided by AlgoKit Utils that builds on top of the core capabilities. It allows you to create, update, delete, call (ABI and otherwise) smart contract apps and the metadata associated with them (including state and boxes).
AppCallArgs
¶
All calls to smart contracts will allow you to optionally specify the arguments you want to pass in to the call.
This type is a union of two types: RawAppCallArgs
and ABIAppCallArgs
.
RawAppCallArgs
¶
RawAppCallArgs
allows you to explicitly specify all of the arguments and has the following properties (all of which are optional):
accounts: (string | algosdk.Address)[]
- Any accounts to add to the accounts array either as thestring
oralgosdk.Address
representation of the public address of the account(s)appArgs: (Uint8Array | string)[]
- Any arguments to pass to the smart contract call, either as the binary representation or a string (that will be encoded to binary usingTextEncoder
)boxes: (BoxReference | BoxIdentifier | algosdk.BoxReference)[]
- Any boxes to load to the boxes arrayapps: number[]
: The ID of any apps to load to the foreign apps arrayassets: number[]
: The ID of any assets to load to the foreign assets arraylease: string | Uint8Array
: A lease to assign to the transaction to enforce a mutually exclusive transaction (useful to prevent double-posting and other scenarios)rekeyTo: string | SendTransactionFrom
: An account or account address that should be authorised to transact on behalf of the account the app call is sent from after the app transaction is processed; note: use with extreme caution and review the official rekey guidance first
ABIAppCallArgs
¶
ABIAppCallArgs
allows you to specify an ARC-0004 ABI call
method: algosdk.ABIMethodParams | algosdk.ABIMethod
- The ABI method to callmethodArgs: ABIAppCallArg[]
- The arguments to pass to the ABI call, which can be one of:algosdk.ABIArgument
- Which can be one of:boolean
number
bigint
string
Uint8Array
- An array of one of the above types
algosdk.TransactionWithSigner
TransactionToSign
algosdk.Transaction
Promise<SendTransactionResult>
- which allows you to use an AlgoKit Utils method call that returns a transaction without needing to await the call and extract the transaction, if you do this be sure to useskipWaiting: true
when specifying the sending parameters so you get the transaction without sending it to the networkboxes: (BoxReference | BoxIdentifier | algosdk.BoxReference)[]
- Any boxes to load to the boxes arraylease: string | Uint8Array
: A lease to assign to the transaction to enforce a mutually exclusive transaction (useful to prevent double-posting and other scenarios)rekeyTo: string | SendTransactionFrom
: An account or account address that should be authorised to transact on behalf of the account the app call is sent from after the app transaction is processed; note: use with extreme caution and review the official rekey guidance first
Utility methods¶
If you want to manually construct a transaction, but use these types to specify the arguments then you can use the following methods:
algokit.getAppArgsForTransaction
- Takes aRawAppCallArgs
object and returns the corresponding fields ready to set onto analgosdk.Transaction
algokit.getAppArgsForABICall
- Takes aABIAppCallArgs
object and returns the corresponding fields ready to pass intoaddMethodCall
onAtomicTransactionComposer
Referencing boxes¶
To reference a box in a transaction using AlgoKit Utils, you can specify one of the following types:
BoxIdentifier
- Which can be one of:string
- Which will be encoded as a box name usingTextEncoder
Uint8Array
- Which will be used directlySendTransactionFrom
- Which will be converted into the public address of the sender corresponding to the account and the public key encoded to binary- This type of encoding is compatible with directly referencing an account address within the smart contract (e.g.
(address := pt.abi.Address()).set(pt.Txn.sender())
in PyTEAL)
- This type of encoding is compatible with directly referencing an account address within the smart contract (e.g.
BoxReference
- Which is an interface that has two fields:appId: number
- The app IDname: BoxIdentifier
- The name, per the above typealgosdk.BoxReference
- The in-built algosdkBoxReference
type, which has two properties:appIndex: number
name: UInt8Array
- The name in binary
If you specify a BoxIdentifier
directly outside of the BoxReference
type then the behaviour is to load the box from the current app the transaction that box identifier appears in. To see more about how box references work consult the official documentation.
BoxName
¶
To get a box reference when reading box state there is a helpful BoxName
type that is exposed, which provides the following properties:
name: string
nameBase64: string
nameRaw: Uint8Array
Creating and updating apps¶
createApp
¶
To create an app you can call algokit.createApp(createPayload, algod)
. See the tests for an example.
The payload to configure an app consists of a union of SendTransactionParams
and the following properties:
- Required
from: SendTransactionFrom
- The account (with private key loaded) that will send the transactionapprovalProgram: Uint8Array | string
- The approval program as raw teal (string) or compiled teal, base 64 encoded as a byte array (Uint8Array)clearStateProgram: Uint8Array | string
- The clear state program as raw teal (string) or compiled teal, base 64 encoded as a byte array (Uint8Array)schema: AppStorageSchema
- The storage schema to request for the created apponCompleteAction?: algosdk.OnApplicationComplete
- The on-completion action to specify for the call; defaults to NoOp- Optional:
transactionParams: SuggestedParams
- Any transaction parametersnote: TransactionNote
- A transaction noteargs: AppCallArgs
- Any arguments passed in to the app call
If you pass in approvalProgram
or clearProgram
as a string then it will automatically be compiled using Algod and the compilation result will be returned from the function (including the source map). To skip this behaviour you can pass in the compiled TEAL as Uint8Array
.
If you pass in args that represent an ABI then it will use an AtomicTransactionComposer
to construct and send the transaction(s). Because it's possible that other transactions may be present as ABI arguments, the full set of transactions that were sent are returned in transactions
and the primary transaction for the create call will also be available in transaction
. If you pass in the atc
or skipSending: true
then it won't execute the transaction and will simply return the transaction(s). The return
value will have any ABI return value within it.
updateApp
¶
To update an app you can call algokit.updateApp(updatePayload, algod)
.
The update payload and behaviour is the same as createApp
with two payload differences:
schema
is not present, since it can only be set when creating a smart contractappId: number
is present (required), which specifies the ID of the app to update
Calling an app¶
To call an app outside of creation or update you can call algokit.callApp(callPayload, algod)
.
The payload to configure an app call consists of a union of SendTransactionParams
and the following properties:
-
Required:
-
appId: number
- The ID of the app to call callType: AppCallType | algosdk.OnApplicationComplete
- The on-completion action for the call (either as analgosdk.OnApplicationComplete
enum or a string enum)-
from: SendTransactionFrom
- The account (with private key loaded) that will send the transaction -
Optional:
transactionParams: SuggestedParams
- Any transaction parametersnote: TransactionNote
- A transaction noteargs: AppCallArgs
- Any arguments passed in to the app call
If you pass in args that represent an ABI then it will use an AtomicTransactionComposer
to construct and send the transaction(s). Because it's possible that other transactions may be present as ABI arguments, the full set of transactions that were sent are returned in transactions
and the primary transaction for the create call will also be available in transaction
. If you pass in the atc
or skipSending: true
then it won't execute the transaction and will simply return the transaction(s). The return
value will have any ABI return value within it.
Accessing state¶
Global state¶
To access and parse global state you can use the following methods:
algokit.getAppGlobalState(appId, algod)
- Returns the current global state for the given app ID decoded into an object keyed by the UTF-8 representation of the state key with various parsed versions of the value (base64, UTF-8 and raw binary)decodeAppState(state)
- Takes the raw response from algod API for global state and returned a friendly decoded object (this is automatically used bygetAppGlobalState
)
Local state¶
To access and parse local state you can use the following methods:
algokit.getAppLocalState(appId, algod)
- Returns the current local state for the given app ID decoded into an object keyed by the UTF-8 representation of the state key with various parsed versions of the value (base64, UTF-8 and raw binary)decodeAppState(state)
- Takes the raw response from algod API for local state and returned a friendly decoded object (this is automatically used bygetAppLocalState
)
Boxes¶
To access and parse box values and names for an app you can use the following methods:
algokit.getAppBoxNames(appId, algod)
- Returns the current box names for the given app IDalgokit.getAppBoxValue(appId, boxName, algod)
- Returns the binary value of the given box name for the given app IDalgokit.getAppBoxValues(appId, boxNames, algod)
- Returns the binary values of the given box names for the given app IDalgokit.getAppBoxValueFromABIType(request, algod)
- Returns the parsed ABI value of the given box name for the given app ID for the provided ABI typealgokit.getAppBoxValuesFromABIType(request, algod)
- Returns the parsed ABI values of the given box names for the given app ID for the provided ABI typealgokit.getBoxReference(box)
- Returns analgosdk.BoxReference
representation of the given box identifier, which is useful when constructing a rawalgosdk.Transaction
Getting an app reference¶
To get reference information and metadata about an existing app you can use the following methods:
algokit.getAppById(appId, algod)
- Returns an app reference by ID from algodalgokit.lookupAccountCreatedApplicationByAddress(indexer, address, getAll?, paginationLimit?)
- Returns all apps created by a given account from indexer