Definition: [
"autonomous agent",
{
"bounce_fees": {
"base": 10000
},
"init": "{
$HOUSE_CUT = 0.1; //We will take this cut on the debut of an NFT in our platform
$ARTIST_CUT = 0.01; //The artist will get this cut from every resale of their NFT
$HALF_HOUR = 1800; //30m = 1800s
$extendDeadLine = $NFT=>$NFT.soldAt <= timestamp + $HALF_HOUR?$NFT || {soldAt: $NFT.soldAt + $HALF_HOUR}: $NFT; //Extend the auction if there is a bid less than half an hour before the auction is closed
if (NOT exists(trigger.data["method"]))
bounce("method field is mandatory");
}",
"getters": "{
$mintedUnits = $NFT=>{
if (NOT var[$NFT])
bounce("NFT not found");
if (NOT asset[$NFT].exists)
bounce("That NFT does not exist");
return asset[$NFT].cap;
};
$tokenInfo = $NFT => {
if (NOT var[$NFT])
bounce("NFT not found");
return var[$NFT] ||
{
isBanned: data_feed[[oracles=this_address, feed_name=$NFT, ifnone=false, ifseveral="last", type="string"]] == "REVOKED",
issuer: asset[$NFT].definer_address,
maxUnits: $mintedUnits($NFT)
};
};
$circulatingSupply = $NFT=>{
if (data_feed[[oracles=this_address, feed_name=$NFT, ifnone=false, ifseveral="last", type="string"]] == "REVOKED")
bounce("That NFT was revoked");
if ($tokenInfo($NFT).issuer != this_address)
bounce("That NFT was not minted by us, thus we don't know how many of them are out in the wild");
return var[$NFT]["unitsSold"];
};
}",
"messages": {
"cases": [
{
"if": "{
NOT var["owner"] //The owner has not been set
}",
"messages": [
{
"app": "state",
"state": "{
var["owner"] = "IUU43O7TS2TBYKAPGKUARDZHOTAE275A"; //Set the Owner to my address
var["debug"] = unit[response_unit];
}"
}
]
},
{
"if": "{
trigger.address == var["owner"]
}",
"init": "{
if (NOT exists(trigger.data["method"]))
bounce("method field is mandatory");
}",
"messages": {
"cases": [
{
"if": "{
trigger.data["method"] == "mint"
}",
"init": "{
if (NOT exists(trigger.data["amount"]))
bounce("amount field is mandatory");
if (NOT is_valid_amount(trigger.data["amount"]))
bounce("The amount of NFT copies to mint is not valid");
if (NOT exists(trigger.data["ipfs"]))
bounce("ipfs field is mandatory");
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");
if (NOT exists(trigger.data["endTime"]))
bounce("endTime field is mandatory");
if (NOT is_integer(trigger.data["endTime"]))
bounce("endTime field is not a timestamp");
if (trigger.data["endTime"] <= timestamp)
bounce("The endTime cannot be set in the past");
if (trigger.data["endTime"] - timestamp > 2628000)
bounce("You cannot set the end time in more than 30 days");
}",
"messages": {
"cases": [
{
"if": "{
trigger.data["amount"] == 1
}",
"messages": [
{
"app": "asset",
"payload": {
"cap": 1,
"is_private": false,
"is_transferrable": true,
"auto_destroy": false,
"fixed_denominations": false,
"issued_by_definer_only": true,
"cosigned_by_definer": false,
"spender_attested": false
}
},
{
"app": "state",
"state": "{
var[response_unit] = {
bid: 0, //Max current bid (a NFT can have this field because it was resold. Check for price field instead)
by: trigger.data["seller"],
at: timestamp, //Max bid time
mintedAt: timestamp, //Mint date
ipfs: trigger.data["ipfs"], //Hash of the content
author: trigger.data["seller"], //The original seller
soldAt: trigger.data["endTime"], //End of the auction
soldBy: trigger.data["seller"] //Who is currently selling the NFT
};
}"
}
]
},
{
"init": "{
if (NOT exists(trigger.data["price"]))
bounce("price field is mandatory if you intend to sell more than one NFT copy");
if (trigger.data["price"] < 20000)
bounce("The minium price is 20000 bytes");
if (NOT is_valid_amount(trigger.data["price"]))
bounce("price is not valid");
}",
"messages": [
{
"app": "asset",
"payload": {
"cap": "{trigger.data["amount"]}",
"is_private": false,
"is_transferrable": true,
"auto_destroy": false,
"fixed_denominations": false,
"issued_by_definer_only": true,
"cosigned_by_definer": false,
"spender_attested": false
}
},
{
"app": "state",
"state": "{
var[response_unit] = {
price: trigger.data["price"], //Sale price (this field is only present if the first sale was a fixed price one)
at: timestamp, //Max bid time
mintedAt: timestamp, //Mint date
ipfs: trigger.data["ipfs"], //Hash of the content
unitsSold: 0,
maxUnits: trigger.data["amount"],
author: trigger.data["seller"], //The original seller
soldAt: trigger.data["endTime"], //End of the auction
soldBy: trigger.data["seller"] //Who is currently selling the NFT
};
}"
}
]
}
]
}
},
{
"if": "{
trigger.data["method"] == "payout"
}",
"init": "{
$balance = balance["base"];
if ($balance - storage_size - 200000 <= 0)
bounce("There are not enough funds to withdraw");
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$balance - storage_size - 200000}"
}
]
}
}
]
},
{
"if": "{
trigger.data["method"] == "approve"
}",
"init": "{
if (NOT exists(trigger.data["NFT"]))
bounce("NFT field is mandatory");
$NFT = var[trigger.data["NFT"]];
if (NOT $NFT)
bounce("That NFT is not known by this AA");
if (NOT $NFT.pendingAproval)
bounce("That NFT is not pendingAproval");
}",
"messages": [
{
"app": "state",
"state": "{
var[trigger.data["NFT"]] ||= {pendingAproval: '', duration: '', foreign: true, bid: 20000, by: $NFT.soldBy, at: timestamp, soldAt: timestamp + $NFT.duration};
}"
}
]
},
{
"if": "{
trigger.data["method"] == "revoke"
}",
"init": "{
if (NOT exists(trigger.data["NFT"]))
bounce("NFT field is mandatory");
}",
"messages": [
{
"app": "data_feed",
"payload": {
"{trigger.data["NFT"]}": "REVOKED"
}
}
]
},
{
"if": "{
trigger.data["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}"
}
]
}
},
{
"app": "state",
"state": "{
var["owner"] = trigger.data["newOwner"];//Ownership is transferred
}"
}
]
}
]
}
},
{
"if": "{
trigger.data["method"] == "BUY"
}",
"init": "{
if (NOT exists (trigger.data["NFT"]))
bounce("NFT field is mandatory");
$NFT = var[trigger.data["NFT"]];
$isAuction = typeof($NFT.bid) == "number";
$hasBidders = (NOT $NFT.by)?false:($NFT.soldBy != $NFT.by);//Booleans cannot be compared
if (NOT $NFT)
bounce("This NFT was not minted by us nor we listed it for sale");
if (timestamp > $NFT.soldAt){
if ($isAuction){
if ($hasBidders) //You can still buy it if there were no bidders
bounce("The auction is over");
}
else
bounce("The auction is already over");
}
}",
"messages": {
"cases": [
{
"if": "{
$isAuction
}",
"init": "{
if (trigger.output[[asset=base]].amount < 20000)
bounce("The minimum bid is 20000 bytes");
if (trigger.output[[asset=base]].amount <= $NFT.bid)
bounce("Your bid is lower or equal to the last bid. You must increase it");
if ($NFT.soldBy == trigger.address)
bounce("You cannot bid on your own auction");
}",
"messages": [
{
"app": "payment",
"if": "{
$NFT.by != $NFT.seller
}",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$NFT.by}",
"amount": "{$NFT.bid - 10000}"
}
]
}
},
{
"app": "state",
"state": "{
$NFT.bid = trigger.output[[asset=base]].amount;
$NFT.by = trigger.address;
var[trigger.data["NFT"]] ||= $extendDeadLine($NFT);
}"
}
]
},
{
"init": "{
if (NOT asset[trigger.data["NFT"]].exists)
bounce("That asset does not exists");
if (asset[trigger.data["NFT"]].definer_address != this_address)
bounce("We have not listed that asset for sale");
if ($NFT.unitsSold == $NFT.maxUnits)
bounce("All NFT copies have been already sold");
if (trigger.output[[asset=base]].amount < $NFT.price)
bounce("Your payment is lower than the NFT price");
}",
"messages": [
{
"app": "payment",
"if": "{
floor($NFT.price * (1-$HOUSE_CUT) - 10000, 0) > 0
}",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$NFT.soldBy}",
"amount": "{floor($NFT.price * (1-$HOUSE_CUT) - 10000, 0)}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{trigger.data['NFT']}",
"outputs": [
{
"address": "{trigger.address}",
"amount": 1
}
]
}
},
{
"app": "state",
"state": "{
var[trigger.data["NFT"]] ||= {unitsSold: $NFT.unitsSold + 1};
}"
}
]
}
]
}
},
{
"if": "{
trigger.data["method"] == "CLAIM"
}",
"init": "{
if (NOT exists(trigger.data["NFT"]))
bounce("NFT field is mandatory");
$NFT = var[trigger.data["NFT"]];
if (timestamp <= $NFT.soldAt)
bounce("The auction is not over yet");
}",
"messages": {
"cases": [
{
"if": "{//NFT was first sold
$NFT.soldBy != $NFT.author
}",
"messages": [
{
"app": "payment",
"if": "{
floor($NFT.bid * (1-$HOUSE_CUT) - 10000, 0) > 0 //enough to be worth paying
AND $NFT.soldBy != $NFT.by //there is at least a bid
}",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$NFT.soldBy}",
"amount": "{floor($NFT.bid * (1-$HOUSE_CUT) - 10000, 0)}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{trigger.data['NFT']}",
"outputs": [
{
"address": "{$NFT.by}",
"amount": 1
}
]
}
},
{
"app": "state",
"state": "{ //Reset bid and by fields
var[trigger.data["NFT"]] ||= {bid: 0, by: ''};
}"
}
]
},
{
"messages": [
{
"app": "payment",
"if": "{
$NFT.soldBy != $NFT.by //Do not pay if there were no bids as the seller would be stealing money from the contract
}",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$NFT.soldBy}",
"amount": "{floor($NFT.bid * (1-$ARTIST_CUT) - 10000, 0)}"
}
]
}
},
{
"app": "payment",
"if": "{
floor($NFT.bid * $ARTIST_CUT, 0) - 10000 > 0
AND is_valid_address($NFT.author)
}",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$NFT.author}",
"amount": "{floor($NFT.bid * $ARTIST_CUT, 0) - 10000}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{trigger.data['NFT']}",
"outputs": [
{
"address": "{$NFT.by}",
"amount": 1
}
]
}
}
]
}
]
}
},
{
"if": "{//[PUBLIC] Resell a NFT
trigger.data["method"] == "SELL"
}",
"init": "{
//Parameter validation
if (NOT exists(trigger.data["endTime"]))
bounce("endTime field is mandatory");
if (trigger.data["endTime"] < timestamp)
bounce("You cannot set the end time in the past");
if (trigger.data["endTime"] - timestamp > 2628000)
bounce("You cannot set the end time in more than 30 days");
if (NOT exists(trigger.data["initialPrice"]))
bounce("initialPrice field is mandatory");
if (NOT is_valid_amount(trigger.data["initialPrice"]))
bounce("initialPrice must be a valid amount");
if (trigger.data["initialPrice"] < 20000)
bounce("The minimum initialPrice is 20000 bytes");
//NFT validation
if (trigger.output[[asset!=base]].asset == "ambigous")
bounce("You cannot send more than one NFT type at a time");
if (NOT var[trigger.output[[asset!=base]].asset])
bounce("You need to send an actual NFT but you are sending only bytes");
$NFT = var[trigger.output[[asset!=base]].asset];
if (NOT $NFT)
bounce("This NFT was not minted by us nor we listed it for sale");
if (trigger.output[[asset!=base]].amount!=1)
bounce("You cannot auction more than 1 copy of an NFT at a time");
if (data_feed[[oracles=this_address, feed_name=trigger.output[[asset!=base]].asset, ifnone=false, ifseveral="last", type="string"]] == "REVOKED")
bounce("We revoked the trading of that token probably due to copyright reasons");
if (typeof($NFT.bid) == "number" AND $NFT.bid != 0)
bounce("A copy of that NFT is already being auctioned." || timestamp > $NFT.soldAt ? "The auction ends at " || timestamp_to_string($NFT.soldAt) || " UTC" : "The auction has already ended but it has not been claimed. You can close it yourself even if you are not the max bidder.");
}",
"messages": [
{
"app": "state",
"state": "{
$NFT.bid = trigger.data["initialPrice"];
$NFT.by = trigger.address;
$NFT.soldBy = trigger.address;
$NFT.at = timestamp;
$NFT.soldAt = trigger.data["endTime"];
var[trigger.output[[asset!=base]].asset] ||= $NFT;
}"
}
]
},
{
"if": "{
trigger.data["method"] == "PRELIST"
}",
"init": "{
if (NOT exists(trigger.data["NFT"]))
bounce("NFT field is mandatory");
if (NOT asset[trigger.data["NFT"]].exists)
bounce("That NFT does not exist within the Obyte network");
if (NOT asset[trigger.data["NFT"]].is_transferrable)
bounce("That NFT is not tradeable");
if (NOT exists(trigger.data["ipfs"]))
bounce("ipfs field is mandatory");
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");
if (NOT exists(trigger.data["duration"]))
bounce("duration field is mandatory. Enter the auction duration in seconds");
if (NOT is_integer(trigger.data["duration"]))
bounce("duration field is not a valid amount of seconds");
if (trigger.data["duration"] > 2628000)
bounce("The auction cannot last more than 30 days");
if (NOT exists(trigger.data["pairing"])) //TODO MAYBE REMOVE
bounce("Pairing code is mandatory. We need it in case we have any questions about your NFT");
}",
"messages": [
{
"app": "state",
"state": "{
var[trigger.data["NFT"]] = {
mintedAt: unit[trigger.data["NFT"]].timestamp,
ipfs: trigger.data["ipfs"], //Hash of the content
author: 'foreign', //The original seller
soldBy: trigger.data["seller"],
duration: trigger.data["duration"] //Duration of the auction in seconds
};
}"
}
]
}
]
}
}
]