Skip to content

Typed application clients

Typed application clients are automatically generated, typed Python deployment and invocation clients for smart contracts that have a defined ARC-56 or ARC-32 application specification so that the development experience is easier with less upskill ramp-up and less deployment errors. These clients give you a type-safe, intellisense-driven experience for invoking the smart contract.

Typed application clients are the recommended way of interacting with smart contracts. If you don’t have/want a typed client, but have an ARC-56/ARC-32 app spec then you can use the non-typed application clients and if you want to call a smart contract you don’t have an app spec file for you can use the underlying app management and app deployment functionality to manually construct transactions.

Generating an app spec

You can generate an app spec file:

Generating a typed client

To generate a typed client from an app spec file you can use AlgoKit CLI:

> algokit generate client application.json --output /absolute/path/to/client.py

Note: AlgoKit Utils >= 3.0.0 is compatible with the older 1.x.x generated typed clients, however if you want to utilise the new features or leverage ARC-56 support, you will need to generate using >= 2.x.x. See AlgoKit CLI generator version pinning for more information on how to lock to a specific version.

Getting a typed client instance

To get an instance of a typed client you can use an AlgorandClient instance or a typed app Factory instance.

The approach to obtaining a client instance depends on how many app clients you require for a given app spec and if the app has already been deployed:

App is deployed

Resolve App by ID

Single Typed App Client Instance:

# Typed: Using the AlgorandClient extension method
typed_client = algorand.client.get_typed_app_client_by_id(
MyContractClient, # Generated typed client class
app_id=1234,
# ...
)
# or Typed: Using the generated client class directly
typed_client = MyContractClient(
algorand,
app_id=1234,
# ...
)

Multiple Typed App Client Instances:

# Typed: Using a typed factory to get multiple client instances
typed_client1 = typed_factory.get_app_client_by_id(
app_id=1234,
# ...
)
typed_client2 = typed_factory.get_app_client_by_id(
app_id=4321,
# ...
)

Resolve App by Creator and Name

Single Typed App Client Instance:

# Typed: Using the AlgorandClient extension method
typed_client = algorand.client.get_typed_app_client_by_creator_and_name(
MyContractClient, # Generated typed client class
creator_address="CREATORADDRESS",
app_name="contract-name",
# ...
)
# or Typed: Using the static method on the generated client class
typed_client = MyContractClient.from_creator_and_name(
algorand,
creator_address="CREATORADDRESS",
app_name="contract-name",
# ...
)

Multiple Typed App Client Instances:

# Typed: Using a typed factory to get multiple client instances by name
typed_client1 = typed_factory.get_app_client_by_creator_and_name(
creator_address="CREATORADDRESS",
app_name="contract-name",
# ...
)
typed_client2 = typed_factory.get_app_client_by_creator_and_name(
creator_address="CREATORADDRESS",
app_name="contract-name-2",
# ...
)

App is not deployed

Deploy a New App

# Typed: For typed clients, you call a specific creation method rather than generic 'create'
typed_client, response = typed_factory.send.create.{METHODNAME}(
# ...
)

Deploy or Resolve App Idempotently by Creator and Name

# Typed: Using the deploy method on a typed factory
typed_client, response = typed_factory.deploy(
on_update=OnUpdate.UpdateApp,
on_schema_break=OnSchemaBreak.ReplaceApp,
# The parameters for create/update/delete would be specific to your generated client
app_name="contract-name",
# ...
)

Creating a typed factory instance

If your scenario calls for an app factory, you can create one using the below:

# Typed: Using the AlgorandClient extension method
typed_factory = algorand.client.get_typed_app_factory(MyContractFactory) # Generated factory class
# or Typed: Using the factory class constructor directly
typed_factory = MyContractFactory(algorand)

Client usage

See the official usage docs for full details about typed clients.

Below is a realistic example that deploys a contract, funds it if newly created, and calls a "hello" method:

# Typed: Complete example using a typed application client
import algokit_utils
from artifacts.hello_world.hello_world_client import (
HelloArgs, # Generated args class
HelloWorldFactory, # Generated factory class
)
# Get Algorand client from environment variables
algorand = algokit_utils.AlgorandClient.from_environment()
deployer = algorand.account.from_environment("DEPLOYER")
# Create the typed app factory
typed_factory = algorand.client.get_typed_app_factory(
HelloWorldFactory, default_sender=deployer.address
)
# Deploy idempotently - creates if it doesn't exist or updates if changed
typed_client, result = typed_factory.deploy(
on_update=algokit_utils.OnUpdate.AppendApp,
on_schema_break=algokit_utils.OnSchemaBreak.AppendApp,
)
# Fund the app with 1 ALGO if it's newly created
if result.operation_performed in [
algokit_utils.OperationPerformed.Create,
algokit_utils.OperationPerformed.Replace,
]:
algorand.send.payment(
algokit_utils.PaymentParams(
amount=algokit_utils.AlgoAmount(algo=1),
sender=deployer.address,
receiver=typed_client.app_address,
)
)
# Call the hello method on the smart contract
name = "world"
response = typed_client.send.hello(args=HelloArgs(name=name)) # Using generated args class