Overview

An application is a MUFL program that implements packet state transition logic. Each ADAPT packet contains a fully-compiled application that provides business logic overseeing all behavior of the packet. An application constitutes the main body of a packet and is akin to the main function in C.

application MyApp loads library Cryptography { 
    ... // some code. 
}

Application source files must use the .mu file extension.

Applications may declare variables and functions and may access public variables and functions from libraries.

The main purpose of an application is to implement transactions (externally-exposed functions) that constitute the packet interface for an ADAPT packet.

Here’s an example of a MUFL application:

application pinger_ponger 
loads libraries
    identity_proof_document, 
    attestation_document, 
    native_attestation_document, 
    browser_attestation_document,
    address_document,
    continuation,
    current_transaction_info,
    transaction_message_decoder,
    integration_test_api
    uses transactions 
{
    hidden // private data and function definitions
    {
        previous_count is int = 0.
        diff = (#$DIFF == "" ?? 1 ; _str_to_number #$DIFF).
        fn make_ping (packet_id: global_id, count: int)
        {
            integration_test_api::custom_message "Received ping: " count "\n".
            if previous_count != 0 && previous_count - diff * 2 != count {
                _abort_transaction ("Invalid ping value received. Expected: " + (_str (previous_count - diff * 2)) + ", obtained: " + (_str count)).
            }

            previous_count -> count.
    
            if count == 0 {
                integration_test_api::exit 0.
                return ::transaction::success [].
            }
    
            return ::transaction::success [
                ::transaction::action::send packet_id ($name -> "::pinger_ponger::ping", $targ -> (count - diff))
            ].
        }
    }
    
    // transaction
    trn ping_init
    _:($count -> count: int, $from -> packet_id: global_id)
    {
        current_transaction_info::validate_origin_or_abort (::transaction::envelope::origin::user,).
        if count == 0 {
            _abort_transaction "Obtained zero count value.". 
        }
    
        return make_ping packet_id count.
    } 


    trn ping
    count: int
    {
        packet_id = current_transaction_info::get_external_envelope_or_abort() $from.
    
        return make_ping packet_id count.
    }
}

For transaction implementation details, refer to Defining Transactions (The trn Statement).

Hash Identifiers

Compiled applications are content-hashed. The output file produced by the compiler uses the application’s hash as the name. Any change to the application’s code, any library that it loads, or any of the applications used by its nested packets cause a change in the hash ID of the application.