[
"autonomous agent",
{
"bounce_fees": {
"base": 10000
},
"init": "{
$BOUNCE_FEE = 10000;
$TYPICAL_FEE = 1000;
$REIMBURSEMENT = $BOUNCE_FEE - $TYPICAL_FEE;
$GBYTE = 1000000000;
$EXCHANGE_RATE_ORACLE = 'F4KHJUCLJKY4JV7M5F754LAJX4EB7M4N';
}",
"messages": {
"cases": [
{
"if": "{ trigger.data.payer }",
"init": "{
$payee = trigger.address;
$payer = trigger.data.payer otherwise bounce("payer field is missing");
$period = trigger.data.period otherwise bounce("period field is missing");
$amount = trigger.data.amount otherwise bounce("amount field is missing");
$currency = trigger.data.currency otherwise 'base';
$reference = sha256($payer || $payee || $period || $amount || $currency );
if ($currency != 'base') {
if (! data_feed[[oracles=$EXCHANGE_RATE_ORACLE,feed_name='GBYTE_' || $currency,ifnone=false]]) bounce("unsupported currency: " || $currency);
}
if (var[$reference]) bounce("contract already exists");
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$REIMBURSEMENT}"
}
]
}
},
{
"app": "state",
"state": "{
var[$reference] = 'requested';
var[$reference||'.payee'] = $payee;
var[$reference||'.payer'] = $payer;
var[$reference||'.period'] = $period;
var[$reference||'.amount'] = $amount;
var[$reference||'.currency'] = $currency;
response['reference'] = $reference;
response['status'] = var[$reference];
response['message'] = 'Recurring contract requested';
}"
}
]
},
{
"if": "{ trigger.data.payee}",
"init": "{
$payer = trigger.address;
$payee = trigger.data.payee otherwise bounce("payee field is missing");
$period = trigger.data.period otherwise bounce("period field is missing");
$amount = trigger.data.amount otherwise bounce("amount field is missing");
$currency = trigger.data.currency otherwise 'base';
$reference = sha256($payer || $payee || $period || $amount || $currency);
if ($currency == 'base') {
$exchange_rate = 1;
} else {
$exchange_rate_gbyte = data_feed[[oracles=$EXCHANGE_RATE_ORACLE,feed_name='GBYTE_' || $currency,ifnone=false]] otherwise bounce("unsupported currency: " || $currency);
$exchange_rate = $GBYTE / $exchange_rate_gbyte; // exchange rate in bytes
}
$minimum_payment = $TYPICAL_FEE + round($amount * $exchange_rate);
if (!var[$reference]) bounce("no such contract, verify contract conditions");
if (var[$reference] == 'authorized') bounce('contract has already been authorized');
if (trigger.output[[asset=base]] < $minimum_payment) bounce("minium payment is " || $minimum_payment);
}",
"messages": [
{
"app": "state",
"state": "{
var[$payer] = trigger.output[[asset=base]] - $TYPICAL_FEE;
var[$reference] = 'authorized';
var[$reference || '.next_payment'] = timestamp;
response['reference'] = $reference;
response['status'] = var[$reference];
response['balance'] = var[$payer];
response['message'] = 'Recurring contract authorized';
}"
}
]
},
{
"if": "{ trigger.data.action AND trigger.data.action == 'cancel' }",
"init": "{
$reference = trigger.data.reference otherwise bounce("reference field is missing");
$payee = var[$reference || '.payee'];
$payer = var[$reference || '.payer'];
if (!var[$reference]) bounce("No such contract");
if (trigger.address != $payer AND trigger.address != $payee) bounce("Unauthorized");
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$REIMBURSEMENT}"
}
]
}
},
{
"app": "state",
"state": "{
var[$reference] = 'cancelled';
response['reference'] = $reference;
response['status'] = var[$reference];
response['message'] = 'Recurring contract cancelled';
}"
}
]
},
{
"if": "{ trigger.data.action AND trigger.data.action == 'withdraw' }",
"init": "{
$account = trigger.address;
$balance = var[$account] otherwise bounce("No such account");
$amount = trigger.data.amount otherwise $balance;
if ($amount > $balance) bounce("Invalid withdrawal amount. Maximum balance is " || $balance);
if ($amount <= 0) bounce("Invalid withdrawal amount. Enter a number greater than zero.");
}",
"messages": [
{
"app": "payment",
"payload": {
"outputs": [
{
"address": "{$account}",
"amount": "{$amount}"
},
{
"address": "{$account}",
"amount": "{$REIMBURSEMENT}"
}
]
}
},
{
"app": "state",
"state": "{
var[$account] -= $amount;
}"
}
]
},
{
"if": "{ trigger.data.reference }",
"init": "{
$reference = trigger.data.reference;
$status = var[$reference] otherwise bounce("No such contract");
$payee = var[$reference || '.payee'];
if (trigger.address != $payee) bounce("Unauthorized");
if ($status != 'authorized') bounce("Contract not authorized yet");
$payer = var[$reference || '.payer'];
$period = var[$reference || '.period'];
$amount = var[$reference || '.amount'];
$currency = var[$reference || '.currency'];
$next_payment = var[$reference || '.next_payment'];
if ($next_payment > timestamp) bounce("Current period has already been paid");
$balance = var[$payer] otherwise bounce("Insufficient funds");
if ($currency == 'base') {
$exchange_rate = 1;
} else {
$exchange_rate_gbyte = data_feed[[oracles=$EXCHANGE_RATE_ORACLE,feed_name='GBYTE_' || $currency,ifnone=false]] otherwise bounce("unsupported currency: " || $currency);
$exchange_rate = $GBYTE / $exchange_rate_gbyte; // exchange rate in bytes
}
$payment_amount = round($amount * $exchange_rate);
if ($balance < $payment_amount) bounce("Insufficient funds");
}",
"messages": [
{
"app": "payment",
"payload": {
"outputs": [
{
"address": "{$payee}",
"amount": "{$payment_amount}"
},
{
"address": "{$payee}",
"amount": "{$REIMBURSEMENT}"
}
]
}
},
{
"app": "state",
"state": "{
var[$payer] -= $payment_amount;
var[$reference || '.next_payment'] = $next_payment + $period;
response['next_payment'] = $next_payment + $period;
response['exchange_rate'] = $exchange_rate;
response['payment_amount'] = $payment_amount;
}"
}
]
},
{
"if": "{
$account = trigger.address;
$deposit = trigger.output[[asset = base]];
$deposit > $BOUNCE_FEE
}",
"messages": [
{
"app": "state",
"state": "{
var[$account] += $deposit;
response['balance'] = var[$account];
response['message'] = 'Added ' || $deposit || ' bytes to your balance';
}"
}
]
},
{
"if": "{ trigger.data.action }",
"init": "{
bounce("Possible values for action: cancel, withdraw");
}",
"messages": [
{
"app": "state",
"state": "{
response['usage'] = 'Possible values for action: cancel, withdraw';
}"
}
]
},
{
"init": "{
bounce("Enter a data field: payer, payee, reference or action");
}",
"messages": [
{
"app": "state",
"state": "{
response['usage'] = 'Enter a data field: payer, payee, reference or action';
}"
}
]
}
]
}
}
]