Definition: [
    "autonomous agent",
    {
        "bounce_fees": {
            "base": 10000
        },
        "init": "{
        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"];
    }",
        "getters": "{
        $getCurrency = $ticker=>{ //Caller should bounce if getCurrency returns false as it means the currency is not supported or was deprecated. You can still calculate exchange rates and convert deprecated currencies to prevent locking NFTs
            return var["CURRENCY_" || $ticker];
        };
        //Does NOT provide GBYTE->anything pairs
        $getExchangeRate = $ticker=>{
            $currency = $getCurrency($ticker) OTHERWISE var["DEPRECATED_" || $ticker];
            if (NOT $currency)
                bounce("That currency was not found");
            $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"]];
            if ($ticker == "USD") //USD -> GBYTE, lets round
                return 1/($multiplier / 1000000000); //Inverse
            return $multiplier / 1000000000;
        };
        $convert = ($amount, $sourceTicker, $destinationTicker)=>{
            $destinationRate = $destinationTicker != "base" ? $getExchangeRate($destinationTicker) : 0;
            $sourceRate = $sourceTicker != "base" ? $getExchangeRate($sourceTicker) : 0;
            if ($amount < 0)
                bounce("You cannot convert a negative amount!");
            if ($sourceTicker != "base")
                if (NOT var["CURRENCY_" || $sourceTicker])
                    bounce("Source currency is unsupported");
            if ($destinationTicker != "base")
                if (NOT var["CURRENCY_" || $destinationTicker])
                    bounce("Destination currency is unsupported");
            if ($sourceTicker == "base") //Convert from GBYTE
                return $amount * (1 / $destinationRate); //Rounding is up to the caller here
            if ($destinationTicker == "base") //Convert to GBYTE
                return round($amount * $sourceRate);    //Automatically rounded
            else{
                $multiplier = $sourceRate * 1 / $getExchangeRate("USD"); //to USD
                $usd = $amount * $multiplier;
                $multiplier2 = 1 / $destinationRate; //to destination currency
                return $usd * $multiplier2; //Rounding is up to the caller here
            }
        };
    }",
        "messages": {
            "cases": [
                {
                    "if": "{
                    NOT $owner //The owner has not been set
                }",
                    "messages": [
                        {
                            "app": "state",
                            "state": "{
                            var["owner"] = "IUU43O7TS2TBYKAPGKUARDZHOTAE275A";
                            var["CURRENCY_USD"] = {
                                oracle1: "F4KHJUCLJKY4JV7M5F754LAJX4EB7M4N", //GBYTE_USD
                                feed1: "GBYTE_USD",
                                oracle2: false,    //FIAT_USD
                                feed2: false
                            };
                        }"
                        }
                    ]
                },
                {
                    "if": "{
                    trigger.address == $owner
                    AND ($method == "payout"
                    OR $method == "transferOwnership"
                    OR $method == "addCurrency"
                    OR $method == "delCurrency")
                }",
                    "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 == "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["DEPRECATED_" || trigger.data["ticker"]] = false; //Undeprecate if applicable
                                        var["CURRENCY_" || trigger.data["ticker"]] = {
                                            oracle1: trigger.data["oracle1"], //x->GBYTE or x->pivot
                                            feed1: trigger.data["feed1"],
                                            oracle2: trigger.data["oracle2"], //pivot->GBYTE
                                            feed2: trigger.data["feed2"]
                                        };
                                    }"
                                    }
                                ]
                            },
                            {
                                "if": "{
                                $method == "delCurrency"
                            }",
                                "init": "{
                                if (NOT exists(trigger.data["ticker"]))
                                    bounce("ticker field is mandatory");
                                if (NOT var["CURRENCY_" || trigger.data["ticker"]])
                                    bounce("That currency is unknown for the AA");
                            }",
                                "messages": [
                                    {
                                        "app": "state",
                                        "state": "{
                                        var["DEPRECATED_" || trigger.data["ticker"]] = var["CURRENCY_" || trigger.data["ticker"]];
                                        var["CURRENCY_" || trigger.data["ticker"]] = false;
                                    }"
                                    }
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    }
]