Definition: [
    "autonomous agent",
    {
        "bounce_fees": {
            "base": 10000
        },
        "init": "{
        $BYTES_IN_GBYTE = 1000000000;
        if (NOT exists(trigger.data["method"]))
            bounce("method field is mandatory");
            
        $method = trigger.data["method"];
        $spendableFunds = balance["base"] - storage_size;   //The max amount the owner can withdraw without bouncing due to not enough funds
        $owner = var["owner"];
        $isHelper = var["helper_" || trigger.address];
        $oracle = var["oracle"];    //Used for GBYTE_USD price
        /*
        ** Provides information about the given license
        */
        $getNFTInfo = $NFT=>{
            $unit = unit[$NFT];
            $info = var["FREE_" || $NFT] OTHERWISE var["NFT_" || $NFT];
            $transferrable = $unit.messages[[.app="asset"]]["payload"]["transferrable"];
            if (NOT $transferrable)//Do not return info about non transferrable NFTs as they cannot get listed in other platforms
                return false;
            return $info || {
                cap: $unit.messages[[.app="asset"]]["payload"]["cap"],
                mintedAt: $unit.timestamp
            };
        };
        $isValidPlainLicense = ($spack, $issuer)=>{
            if (is_valid_signed_package($spack, $issuer))
                return $spack.signed_message["expireDate"] < timestamp;
        };
        $FEE = var["FEE"];
    }",
        "messages": {
            "cases": [
                {
                    "if": "{
                    NOT $owner //The owner has not been set
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var["owner"] = "IUU43O7TS2TBYKAPGKUARDZHOTAE275A";
                            var["CURRENCY_USD"] = {
                                oracle1: "F4KHJUCLJKY4JV7M5F754LAJX4EB7M4N",
                                feed1: "GBYTE_USD",
                                oracle2: false,
                                feed2: false
                            };
                            var["FEE"] = 0.03;
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    trigger.address == $owner
                    AND ($method == "payout"    //We also check the method so the Owner can also act as an user
                    OR $method == "stopSale"
                    OR $method == "transferOwnership"
                    OR $method == "setHelper"
                    OR $method == "addCurrency"
                    OR $method == "delCurrency"
                    OR $method == "reduceFee"
                    OR $method == "delHelper")
                }",
                    "messages": {
                        "cases": [
                            {
                                "if": "{
                                $method == "payout"
                            }",
                                "messages": [
                                    {
                                        "app": "payment",
                                        "payload": {
                                            "asset": "base",
                                            "outputs": [
                                                {
                                                    "address": "{trigger.address}",
                                                    "amount": "{$spendableFunds}"
                                                }
                                            ]
                                        }
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "transferOwnership"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["newOwner"]))
                                    bounce("newOwner field is mandatory");
                                if (NOT is_valid_address(trigger.data["newOwner"]))
                                    bounce("newOwner field is not a valid address");
                            }",
                                "messages": [
                                    {
                                        "app": "payment",
                                        "payload": {
                                            "asset": "base",
                                            "outputs": [
                                                {
                                                    "address": "{trigger.address}",
                                                    "amount": "{$spendableFunds}"
                                                }
                                            ]
                                        }
                                    },
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["owner"] = trigger.data["newOwner"];
                                    }"
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "reduceFee"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["fee"]))
                                    bounce("fee field is mandatory");
                                if (trigger.data["fee"] <= 0)
                                    bounce("Fee must be an strictly positive value");
                                if (trigger.data["fee"] > $FEE)
                                    bounce("You can only reduce the current fee");
                            }",
                                "messages": [
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["FEE"] = trigger.data["fee"];
                                    }"
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "addCurrency"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["ticker"]))
                                    bounce("ticker field is mandatory");
                                if (NOT exists(trigger.data["oracle1"]))
                                    bounce("oracle1 field is mandatory");
                                if (NOT is_valid_address(trigger.data["oracle1"]))
                                    bounce("oracle1 address is invalid");
                                if (NOT exists(trigger.data["feed1"]))
                                    bounce("feed1 field is mandatory");
                                if (exists(trigger.data["oracle2"])){
                                    if (NOT is_valid_address(trigger.data["oracle2"]))
                                        bounce("oracle2 address is invalid");
                                    if (NOT exists(trigger.data["oracle1"]))
                                        bounce("If you provided oracle2 you have to provide oracle1");
                                    if (NOT exists(trigger.data["feed2"]))
                                        bounce("If you provided oracle2 you have to provide feed2");
                                    if (NOT data_feed[[oracles=trigger.data["oracle2"], feed_name=trigger.data["feed2"], ifseveral="last", ifnone=false]])
                                        bounce("oracle2 does not post that feed");
                                }
                                if (NOT data_feed[[oracles=trigger.data["oracle1"], feed_name=trigger.data["feed1"], ifseveral="last", ifnone=false]])
                                    bounce("oracle1 does not post that feed");    
                            }",
                                "messages": [
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["CURRENCY_" || trigger.data["ticker"]] = {
                                            oracle1: trigger.data["oracle1"],
                                            feed1: trigger.data["feed1"],
                                            oracle2: trigger.data["oracle2"],
                                            feed2: trigger.data["feed2"]
                                        };
                                    }"
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "delCurrency"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["ticker"]))
                                    bounce("ticker field is mandatory");
                                if (NOT var[trigger.data["ticker"]])
                                    bounce("That currency is unknown for the AA");
                            }",
                                "messages": [
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["CURRENCY_" || trigger.data["ticker"]] = false;
                                    }"
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "setHelper"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["helper"]))
                                    bounce("helper field is mandatory");
                                if (NOT is_valid_address(trigger.data["helper"]))
                                    bounce("helper address is invalid");
                            }",
                                "messages": [
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["helper_" || trigger.data["helper"]] = true;
                                    }"
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "delHelper"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["helper"]))
                                    bounce("helper field is mandatory");
                                if (NOT is_valid_address(trigger.data["helper"]))
                                    bounce("helper address is invalid");
                            }",
                                "messages": [
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["helper_" || trigger.data["helper"]] = false;
                                    }"
                                    }
                                ]
                            }
                        ]
                    }
                },
                {
                    "if": "{
                    (trigger.address == $owner OR $isHelper)
                    AND $method == "trust"
                }",
                    "init": "{
                    if (NOT trigger.data["user"])
                        bounce("user field is mandatory");
                    if (NOT is_valid_address(trigger.data["user"]))
                        bounce("user field is an invalid address");
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var["trusted_" || trigger.data["user"]] = true;
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    (trigger.address == $owner OR $isHelper)
                    AND $method == "untrust"
                }",
                    "init": "{
                    if (NOT trigger.data["user"])
                        bounce("user field is mandatory");
                    if (NOT is_valid_address(trigger.data["user"]))
                        bounce("user field is an invalid address");
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var["trusted_" || trigger.data["user"]] = false;
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    (trigger.address == $owner OR $isHelper)
                    AND $method == "untrust"
                }",
                    "init": "{
                    if (NOT trigger.data["NFT"])
                        bounce("NFT field is mandatory");
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var["FREE_" || trigger.data["NFT"]] = var["NFT_" || trigger.data["NFT"]];
                            var["NFT_" || trigger.data["NFT"]] = false;
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    $method == "MINT"
                }",
                    "init": "{
                    if (NOT exists(trigger.data["amount"]))
                        bounce("amount field is mandatory. Set it to 0 for unlimited");
                    if ((NOT is_valid_amount(trigger.data["amount"])) AND trigger.data["amount"] != 0)  //amount=0 => uncapped
                        bounce("The amount of license copies to mint is not valid");
                    if (NOT exists(trigger.data["price"]))
                        bounce("price field is mandatory");
                    $priceCurrency = trigger.data["priceCurrency"] OTHERWISE false;
                    $price = trigger.data["price"]; //Price in the selected currency
                    $isTrusted = var["trusted_" || trigger.address];
                    if ($price <= 0) //Check that price in any currency is > 0
                        bounce("price field must be filled and it must be a positive number");
                    if (NOT exists(trigger.data["priceCurrency"])){  //It is priced in bytes
                        if ($price < 20000)                        //It not worth to sell for under 20KB
                            bounce("The minium price is 20.000 bytes");
                        if (NOT is_valid_amount($price))
                            bounce("price is not valid");
                    }
                    else{
                        if (NOT var["CURRENCY_" || trigger.data["priceCurrency"]])
                            bounce("That currency is currently not supported");
                    }
                    if (exists(trigger.data["maxPeriods"])){    //Periods are discrete to better represent how licenses currently work IRL (sellers may be interested in not selling continous periods)
                        if (NOT is_integer(trigger.data["maxPeriods"]))
                            bounce("maxPeriods must be an integer");
                        if (trigger.data["maxPeriods"] <= 0)
                            bounce("maxPeriods must be positive");
                        if (NOT exists(trigger.data["validity"]))
                            bounce("If you set maxPeriods you have to set validity too");
                    }
                    if (exists(trigger.data["validity"])){
                        if (NOT is_integer(trigger.data["validity"]))
                            bounce("validity must be an integer");
                        if (trigger.data["validity"] <= 0)
                            bounce("You cannot make a license valid for 0s or less");
                    }
                    if (trigger.address == $owner OR $isTrusted){    //These licenses will be listed for sale so we need metadata about them
                        if (NOT exists(trigger.data["ipfs"]))       //meta.json IPFS CID
                            bounce("ipfs field is mandatory");
                        if (NOT exists(trigger.data["title"]))
                            bounce("title field is mandatory");
                        if (length(trigger.data["title"]) > 512)    //Prevent locking AA funds by sending max length titles
                            bounce("The license title must be at most 512 characters long");
                        if (exists(trigger.data["ticker"])){
                            if (length(trigger.data["ticker"] < 128)) //Prevent locking AA funds by sending max length names
                                bounce("The length of the license ticker must be at most 128 characters long");
                        }
                        if (trigger.address == $owner){                //Only the owner can set a third party as the seller to prevent approved sellers to troll another sellers by creating licensed on their name
                            if (NOT exists(trigger.data["seller"]))
                                bounce("seller field is mandatory");
                            if (NOT is_valid_address(trigger.data["seller"]))
                                bounce("The seller address is not valid");
                        }
                        
                        $pendingNaming = var["NFT_" || var["pendingNaming"]];    //Previosly issued license
                    }
                    if (exists(trigger.data["soldAt"])){
                        if (NOT is_integer(trigger.data["soldAt"]))
                            bounce("soldAt must be an integer");
                        if (trigger.data["soldAt"] <= timestamp)
                            bounce("soldAt cannot be set in the past");
                    }
                    if (exists(trigger.data["tranferrable"])){
                        $isTransferrable = exists(trigger.data["validity"]) //Timed licenses are not transferrable
                            ? false
                            : trigger.data["tranferrable"] == "true"
                                ? true
                                : false;
                    }
                    else{
                        $isTransferrable = false;
                    }
                }",
                    "messages": {
                        "cases": [
                            {
                                "if": "{
                                trigger.data["amount"]
                            }",
                                "messages": [
                                    {
                                        "app": "asset",
                                        "payload": {
                                            "cap": "{trigger.data["amount"]}",
                                            "is_private": false,
                                            "is_transferrable": "{$isTransferrable}",
                                            "auto_destroy": false,
                                            "fixed_denominations": false,
                                            "issued_by_definer_only": true,
                                            "cosigned_by_definer": false,
                                            "spender_attested": false
                                        }
                                    },
                                    {
                                        "app": "data",
                                        "if": "{
                                        $pendingNaming
                                    }",
                                        "payload": {
                                            "asset": "{var["recordToData"]}",
                                            "name": "{($pendingNaming.ticker OTHERWISE "Untitled")|| " license"}",
                                            "author": "{$pendingNaming.author}",
                                            "ipfs": "{$pendingNaming.ipfs}",
                                            "type": "LIC",
                                            "decimals": 0
                                        }
                                    },
                                    {
                                        "app": "state",
                                        "state": "{
                                        if (trigger.address == $owner OR $isTrusted){
                                            var["NFT_" || response_unit] = {
                                                price: trigger.data["price"] OTHERWISE false,
                                                priceCurrency: trigger.data["priceCurrency"] OTHERWISE false,
                                                title: trigger.data["title"],
                                                ipfs: trigger.data["ipfs"],
                                                author: trigger.data["seller"],
                                                validity: trigger.data["validity"] OTHERWISE false,
                                                maxPeriods: trigger.data["maxPeriods"] OTHERWISE false,
                                                soldAt: trigger.data["soldAt"] OTHERWISE false,
                                                onSale: true,
                                                type: 'LIC'
                                            };
                                            var["pendingNaming"] = response_unit;
                                        }
                                        else{ //Non trusted NFTs are unnamed (i.e: we never post a data app with metainfo)
                                            var["FREE_" || response_unit] = {
                                                price: trigger.data["price"] OTHERWISE false,
                                                priceCurrency: trigger.data["priceCurrency"] OTHERWISE false,
                                                author: trigger.address,
                                                validity: trigger.data["validity"],
                                                maxPeriods: trigger.data["maxPeriods"],
                                                soldAt: trigger.data["soldAt"] OTHERWISE false,
                                                onSale: true,
                                                type: 'LIC'
                                            };
                                        }
                                    }"
                                    }
                                ]
                            },
                            {
                                "messages": [
                                    {
                                        "app": "asset",
                                        "payload": {
                                            "is_private": false,
                                            "is_transferrable": "{$isTransferrable}",
                                            "auto_destroy": false,
                                            "fixed_denominations": false,
                                            "issued_by_definer_only": true,
                                            "cosigned_by_definer": false,
                                            "spender_attested": false
                                        }
                                    },
                                    {
                                        "app": "data",
                                        "if": "{
                                        $pendingNaming
                                    }",
                                        "payload": {
                                            "asset": "{var["recordToData"]}",
                                            "name": "{($pendingNaming.ticker OTHERWISE "Untitled")|| " license"}",
                                            "author": "{$pendingNaming.author}",
                                            "ipfs": "{$pendingNaming.ipfs}",
                                            "type": "LIC",
                                            "decimals": 0
                                        }
                                    },
                                    {
                                        "app": "state",
                                        "state": "{
                                        if (trigger.address == $owner OR $isTrusted){
                                            var["NFT_" || response_unit] = {
                                                price: trigger.data["price"] OTHERWISE false,
                                                priceCurrency: trigger.data["priceCurrency"] OTHERWISE false,
                                                title: trigger.data["title"],
                                                ipfs: trigger.data["ipfs"],
                                                author: trigger.data["seller"],
                                                validity: trigger.data["validity"] OTHERWISE false,
                                                maxPeriods: trigger.data["maxPeriods"] OTHERWISE false,
                                                onSale: true,
                                                type: 'LIC'
                                            };
                                            var["pendingNaming"] = response_unit;
                                        }
                                        else{
                                            var["FREE_" || response_unit] = {
                                                price: trigger.data["price"] OTHERWISE false,
                                                priceCurrency: trigger.data["priceCurrency"] OTHERWISE false,
                                                author: trigger.address,
                                                validity: trigger.data["validity"],
                                                maxPeriods: trigger.data["maxPeriods"],
                                                onSale: true,
                                                type: 'LIC'
                                            };
                                        }
                                    }"
                                    }
                                ]
                            }
                        ]
                    }
                },
                {
                    "if": "{
                    $method == "END_SALE"
                }",
                    "init": "{
                    if (NOT exists(trigger.data["NFT"]))
                        bounce("NFT field is mandatory");
                    $NFT = var["NFT_" || trigger.data["NFT"]] OTHERWISE var["FREE_" || trigger.data["NFT"]];
                    if (NOT $NFT)
                        bounce("That NFT is not known by this AA");
                    if (trigger.address != $NFT.author)
                        bounce("You cannot stop a sale not created by yourself");
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            if (var["NFT_" || trigger.data["NFT"]])
                                var["NFT_" || trigger.data["NFT"]] ||= {onSale: false};
                            else
                                 var["FREE_" || trigger.data["NFT"]] ||= {onSale: false};
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    trigger.data["method"] == "BUY"
                }",
                    "init": "{
                    $NFT = var["NFT_" || trigger.data["NFT"]] OTHERWISE var["FREE_" || trigger.data["NFT"]];
                    $previousExpiry = var[trigger.address || "_" || trigger.data["NFT"]] OTHERWISE timestamp;
                    if (NOT $NFT)
                        bounce("NFT field is mandatory");
                    if ($NFT.soldAt){
                        if ($NFT.soldAt < timestamp)
                            bounce("That license sale period ended on " || timestamp_to_string($NFT.soldAt) || " UTC");
                    }
                    if (NOT $NFT.onSale)
                        bounce("The owner of that license cancelled its sale. No more copies will be ever sold.");
                    if (exists(trigger.data["periods"])){
                        if (NOT is_integer(trigger.data["periods"]))    //Periods are discrete to better represent how licensing work right now
                            bounce("periods must be an integer");
                        if ($NFT.validity AND $NFT.maxPeriods){ //If it is a timed license with a maximum amount of periods check if the purchase does not exceed max purchasable time
                            if ($previousExpiry + trigger.data["periods"] * $NFT.validity >  timestamp + ($NFT.maxPeriods OTHERWISE 1) * $NFT.validity)
                                bounce("You cannot buy that many periods in advance. You have to wait until your license is closer to expiry date");
                        }
                    }
                    $periods = trigger.data["periods"] OTHERWISE 1;
                    if ($NFT.priceCurrency){ //Not priced in bytes, lets calculate the equivalent value in bytes by doing fiat=>USD=>byte if there is no direct conversion available
                        $currency = var["CURRENCY_" || $NFT.priceCurrency];
                        $multiplier = $currency.feed2
                            ? 1 / data_feed[[oracles=$currency.oracle2, feed_name=$currency.feed2, ifseveral="last"]] * data_feed[[oracles=$currency.oracle1, feed_name=$currency.feed1, ifseveral="last"]]
                            : data_feed[[oracles=$currency.oracle1, feed_name=$currency.feed1, ifseveral="last"]];
                    }
                       $expectedAmount = $NFT.priceCurrency
                        ? round($NFT.price * 1 / $multiplier * $BYTES_IN_GBYTE, 0)
                        : $NFT.price;
                    
                    response["rate"] = $multiplier / $BYTES_IN_GBYTE; //Price per byte
                    response["price"] = $expectedAmount;
                    response["currency"] = $NFT.priceCurrency;
                    if (trigger.output[[asset="base"]].amount < $expectedAmount)
                        bounce("Your payment is lower than the NFT price. You have to send " || $expectedAmount || " bytes");
                    $pendingNaming = var["NFT_" || var["recordToData"]];
                }",
                    "messages": [
                        {
                            "app": "payment",
                            "if": "{
                            floor($expectedAmount * (1 - $FEE), 0) > 0
                        }",
                            "payload": {
                                "asset": "base",
                                "outputs": [
                                    {
                                        "address": "{$NFT.author}",
                                        "amount": "{floor($expectedAmount * (1 - $FEE), 0)}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{trigger.data['NFT']}",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{$periods}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "data",
                            "if": "{
                            $pendingNaming
                        }",
                            "payload": {
                                "asset": "{var["recordToData"]}",
                                "name": "{($pendingNaming.ticker OTHERWISE "Untitled") || " license"}",
                                "author": "{$pendingNaming.author}",
                                "ipfs": "{$pendingNaming.ipfs}",
                                "type": "LIC",
                                "decimals": 0
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            if ($pendingNaming){
                                var["recordToData"] = false;
                            }
                            if ($NFT.validity){ //It is a timed license, lets save expiry date for the buyer
                                var[trigger.address || "_" || trigger.data["NFT"]] = $previousExpiry + $NFT.validity * $periods; //Add the just purchased time to the subscription
                            }
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    $method == "CHANGE_PRICE"
                }",
                    "init": "{
                    if (NOT exists(trigger.data["NFT"]))
                        bounce("NFT field is mandatory");
                    $NFT = var["NFT_" || trigger.data["NFT"]] OTHERWISE var["FREE_" || trigger.data["NFT"]];
                    $isRegisteredNFT = var["NFT_" || trigger.data["NFT"]];
                    if (NOT $NFT)
                        bounce("NFT not found");
                    if ($NFT.author != trigger.address)
                        bounce("You can only change the price of your own licenses!");
                    if (exists(trigger.data["price"])){
                        if (NOT is_integer(trigger.data["price"]))
                            bounce("price must be an integer");
                        if (NOT is_valid_amount(trigger.data["price"]) OR trigger.data["price"] < 20000)
                            bounce("price must be at least 20.000 bytes");
                        if (exists(trigger.data["priceUSD"]))
                            bounce("You cannot set price and priceUSD at the same time");
                    }
                    if (NOT exists(trigger.data["price"]) AND NOT exists(trigger.data["priceUSD"]))
                        bounce("You have to provide either price or priceUSD field");
                    $price = trigger.data["price"] OTHERWISE trigger.data["priceUSD"];
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var[($isRegisteredNFT ? "NFT_" : "FREE_") || trigger.data["NFT"]] ||= {
                                price: exists(trigger.data["price"]) ? $price : false,
                                priceUSD: exists(trigger.data["priceUSD"]) ? $price : false,
                            };
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    $method == "REDEEM"
                }",
                    "init": "{
                    if (NOT exists(trigger.data["signed_message"]))
                        bounce("signed_message field is mandatory");
                    if (NOT exists(trigger.data["authors"]))
                        bounce('authors field is mandatory');
                    if (NOT exists(trigger.data["meta"]))
                        bounce("meta field is mandatory");
                    $spack = {
                        signed_message: trigger.data["signed_message"],
                         authors: trigger.data["authors"]
                    } || trigger.data["meta"];
                    if ($spack.signed_message["amount"])
                        if (NOT is_integer($spack.signed_message["amount"]))
                            bounce("You cannot redeem fractional license periods");
                    if (NOT is_valid_signed_package($spack, $spack.authors[0]["address"]))
                        bounce("The signed message signature is invalid");
                    if (NOT $spack.signed_message["serial"])
                        bounce("The signed message does not contains a serial field");
                    if (NOT $spack.signed_message["NFT"])
                        bounce("The signer of this message did not include a NFT field");
                    //Check if the code has already been redeemed
                    if (var["CODE_" || $spack.signed_message["NFT"] || "_" || sha256($spack.signed_message["serial"])])
                        bounce("That code was already redeemed");
                        
                    //Check for address-bound codes
                    if ($spack.signed_message["claimer"])
                        if ($spack.signed_message["claimer"] != trigger.address)
                            bounce("You cannot claim that NFT from that address");
                    $NFT = var["NFT_" || $spack.signed_message.NFT] OTHERWISE var["FREE_" || $spack.signed_message.NFT];
                    if (NOT $NFT)
                        bounce("That license does not exist");
                    if ($spack.signed_message["expireDate"]){ //Check if the code has expired
                        if ($NFT.soldAt){ //The license sale had an expiration date. Let's check if it is expired
                            if ($NFT.soldAt < timestamp)
                                bounce("The sale of that license has already ended. You cannot claim a copy of it");
                        }
                        if ($spack.signed_message["expireDate"] < timestamp){
                            bounce("That NFT is no longer claimable");
                        }
                    }
                    $signedAmount = $spack.signed_message["amount"] OTHERWISE 1; //A code can grant more than 1 license period
                    if ($NFT.author != $spack.authors[0].address)
                        bounce("The signer of that message is not the issuer of that license");
                    //Uncapped asset, we can issue whatever amount was signed
                    if (NOT $NFT.cap){
                        $periods = $signedAmount;
                    }
                    //If it is going over the cap we need to reduce the claimed amount to match the asset cap
                    else {
                        if ($NFT.unitsSold + $signedAmount > $NFT.cap)
                            $periods = $NFT.cap - $NFT.unitsSold;
                        else
                            $periods = $signedAmount;
                    }
                    
                    //All copies were issued
                    if ($periods == 0)
                        bounce("All copies of that NFT have been already minted");
                }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{$spack.signed_message["NFT"]}",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{$periods}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            if ($NFT.validity){
                                var[trigger.address || "_" || $spack.signed_message["NFT"]] = (var[trigger.address || "_" || $spack.signed_message["NFT"]] OTHERWISE 0) + $periods * $NFT.validity;
                            }
                            var["CODE_" || $spack.signed_message["NFT"] || "_" || sha256($spack.signed_message["serial"])] = true; //Mark as used
                        }"
                        }
                    ]
                }
            ]
        }
    }
]