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 then
                _abort_transaction ("Invalid ping value received. Expected: " + (_str (previous_count - diff * 2)) + ", obtained: " + (_str count)).
            end 

            previous_count -> count.
    
            if count == 0 then
                integration_test_api::exit 0.
                return ::transaction::success [].
            end
    
            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 then
            _abort_transaction "Obtained zero count value.". 
        end
    
        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.