Application Specification | Algorand Developer Portal

Application Specification

Abstract

[!NOTE] This specification will be eventually deprecated by the ARC-56 specification.

An Application is partially defined by it’s methods but further information about the Application should be available. Other descriptive elements of an application may include it’s State Schema, the original TEAL source programs, default method arguments, and custom data types. This specification defines the descriptive elements of an Application that should be available to clients to provide useful information for an Application Client.

Motivation

As more complex Applications are created and deployed, some consistent way to specify the details of the application and how to interact with it becomes more important. A specification to allow a consistent and complete definition of an application will help developers attempting to integrate an application they’ve never worked with before.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 822..

Definitions

Application Specification

The Application Specification is composed of a number of elements that serve to fully describe the Application.

type AppSpec = {

// embedded contract fields, see ARC-0004 for more

contract: ARC4Contract;

// the original teal source, containing annotations, base64 encoded

source?: SourceSpec;

// the schema this application requires/provides

schema?: SchemaSpec;

// supplemental information for calling bare methods

bare_call_config?: CallConfigSpec;

// supplemental information for calling ARC-0004 ABI methods

hints: HintsSpec;

// storage requirements

state?: StateSpec;

}

Source Specification

Contains the source TEAL files including comments and other annotations.

// Object containing the original TEAL source files

type SourceSpec = {

// b64 encoded approval program

approval: string;

// b64 encoded clear state program

clear: string;

}

Schema Specification

The schema of an application is critical to know prior to creation since it is immutable after create. It also helps clients of the application understand the data that is available to be queried from off chain. Individual fields can be referenced from the default argument to provide input data to a given ABI method.

While some fields are possible to know ahead of time, others may be keyed dynamically. In both cases the data type being stored MUST be known and declared ahead of time.

// The complete schema for this application

type SchemaSpec = {

local: Schema;

global: Schema;

}

// Schema fields may be declared explicitly or reserved

type Schema = {

declared: Record<string, DeclaredSchemaValueSpec>;

reserved: Record<string, ReservedSchemaValueSpec>;

}

// Types supported for encoding/decoding

enum AVMType { uint64, bytes }

// string encoded datatype name defined in arc-4

type ABIType = string;

// Fields that have an explicit key

type DeclaredSchemaValueSpec = {

type: AVMType | ABIType;

key: string;

descr: string;

}

// Fields that have an undetermined key

type ReservedSchemaValueSpec = {

type: AVMType | ABIType;

descr: string;

max_keys: number;

}

Bare Call Specification

Describes the supported OnComplete actions for bare calls on the contract.

// describes under what conditions an associated OnCompletion type can be used with a particular method

// NEVER: Never handle the specified on completion type

// CALL: Only handle the specified on completion type for application calls

// CREATE: Only handle the specified on completion type for application create calls

// ALL: Handle the specified on completion type for both create and normal application calls

type CallConfig = 'NEVER' | 'CALL' | 'CREATE' | 'ALL'

type CallConfigSpec = {

// lists the supported CallConfig for each on completion type, if not specified a CallConfig of NEVER is assumed

no_op?: CallConfig

opt_in?: CallConfig

close_out?: CallConfig

update_application?: CallConfig

delete_application?: CallConfig

}

Hints Specification

Contains supplemental information about ARC-0004 ABI methods, each record represents a single method in the ARC-0004 contract. The record key should be the corresponding ABI signature.

NOTE: Ideally this information would be part of the ARC-0004 ABI specification.

type HintSpec = {

// indicates the method has no side-effects and can be call via dry-run/simulate

read_only?: bool;

// describes the structure of arguments, key represents the argument name

structs?: Record<string, StructSpec>;

// describes source of default values for arguments, key represents the argument name

default_arguments?: Record<string, DefaultArgumentSpec>;

// describes which OnCompletion types are supported

call_config: CallConfigSpec;

}

// key represents the method signature for an ABI method defined in 'contracts'
type HintsSpec = Record<string, HintSpec>

Readonly Specification

Indicates the method has no side-effects and can be called via dry-run/simulate

NOTE: This property is made obsolete by ARC-0022 but is included as it is currently used by existing reference implementations such as Beaker

Struct Specification

Each defined type is specified as an array of StructElements.

The ABI encoding is exactly as if an ABI Tuple type defined the same element types in the same order. It is important to encode the struct elements as an array since it preserves the order of fields which is critical to encoding/decoding the data properly.

// Type aliases for readability

type FieldName = string

// string encoded datatype name defined in ARC-0004

type ABIType = string

// Each field in the struct contains a name and ABI type

type StructElement = [FieldName, ABIType]

// Type aliases for readability

type ContractDefinedType = StructElement[]

type ContractDefinedTypeName = string;

// represents an input/output structure

type StructSpec = {

name: ContractDefinedTypeName

elements: ContractDefinedType

}

Default Argument

Defines how default argument values can be obtained. The source field defines how a default value is obtained, the data field contains additional information based on the source value.

Valid values for source are:

Two scenarios where providing default arguments can be useful:

  1. Providing a default value for optional arguments

  2. Providing a value for required arguments such as foreign asset or application references without requiring the client to explicitly determine these values when calling the contract

// ARC-0004 ABI method definition
type ABIMethod = {};
type DefaultArgumentSpec = {

// Where to look for the default arg value

source: "constant" | "global-state" | "local-state" | "abi-method"

// extra data to include when looking up the value

data: string | bigint | number | ABIMethod

}

State Specifications

Describes the total storage requirements for both global and local storage, this should include both declared and reserved described in SchemaSpec.

NOTE: If the Schema specification contained additional information such that the size could be calculated, then this specification would not be required.

type StateSchema = {

// how many byte slices are required

num_byte_slices: number

// how many uints are required

num_uints: number

}

type StateSpec = {

// schema specification for global storage

global: StateSchema

// schema specification for local storage

local: StateSchema

}

Reference Schema

A full JSON schema for application.json can be found in here.

Rationale

The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages.

Backwards Compatibility

All ARCs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The ARC must explain how the author proposes to deal with these incompatibilities. ARC submissions without a sufficient backwards compatibility treatise may be rejected outright.

Test Cases

Test cases for an implementation are mandatory for ARCs that are affecting consensus changes. If the test suite is too large to reasonably be included inline, then consider adding it as one or more files in https://raw.githubusercontent.com/algorandfoundation/ARCs/main/assets/arc-####/.

Reference Implementation

algokit-utils-py and algokit-utils-ts both provide reference implementations for the specification structure and using the data in an ApplicationClient``Beaker provides a reference implementation for creating an application.json from a smart contract.

Security Considerations

All ARCs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. ARC submissions missing the “Security Considerations” section will be rejected. An ARC cannot proceed to status “Final” without a Security Considerations discussion deemed sufficient by the reviewers.

Copyright

Copyright and related rights waived via CCO.