aleoflow 0.1.1

A developer CLI for Aleo — scaffold, build, test, audit, deploy, and generate TypeScript bindings for Leo programs.
// The {{PROJECT_NAME}} program
// A fungible token following the community-standard token.aleo pattern.
//
// NOTE: This template follows the de facto `token.aleo` convention widely
// used across the Aleo ecosystem. It is NOT an officially ratified ARC
// (Aleo Request for Comments) standard -- see README.md for details.

program {{PROJECT_NAME}}.aleo {
    @noupgrade
    constructor() {}

    // Public on-chain balances, tracked in the `account` mapping.
    // These are transparent: anyone can read them on-chain.
    mapping account: address => u64;

    // Private token record (Aleo's UTXO model). Holdings live inside this
    // record in a user's wallet and must be scanned for -- they are NOT
    // stored in a single on-chain mapping. See `aleoflow records list`.
    record Token {
        owner: address,
        amount: u64,
    }

    // Mint tokens privately, producing a new Token record for the receiver.
    // NOTE: Intentionally ungated for this template. Production use should
    // add access control (e.g. checking self.caller against an admin
    // address or a roles mapping) to prevent unauthorized minting.
    fn mint(receiver: address, amount: u64) -> Token {
        return Token {
            owner: receiver,
            amount: amount,
        };
    }

    // Private UTXO transfer: consumes the caller's Token record and returns
    // a change record (back to the sender) plus a transferred record (to
    // the receiver). No on-chain state is written.
    fn transfer(sender: Token, receiver: address, amount: u64) -> (Token, Token) {
        let difference: u64 = sender.amount - amount;
        let remaining: Token = Token {
            owner: sender.owner,
            amount: difference,
        };
        let transferred: Token = Token {
            owner: receiver,
            amount: amount,
        };
        return (remaining, transferred);
    }

    // Public transfer: decrements the sender's public `account` balance and
    // increments the receiver's, via the on-chain finalize block.
    fn transfer_public(public sender: address, public receiver: address, public amount: u64) -> Final {
        assert_eq(self.caller, sender);
        return final {
            let sender_amount: u64 = Mapping::get_or_use(account, sender, 0u64);
            Mapping::set(account, sender, sender_amount - amount);
            let receiver_amount: u64 = Mapping::get_or_use(account, receiver, 0u64);
            Mapping::set(account, receiver, receiver_amount + amount);
        };
    }

    // Convert private tokens to public: consumes a Token record and credits
    // the receiver's public `account` balance on-chain.
    // Pass self.caller as the receiver to convert to your own public balance.
    fn private_to_public(sender: Token, public receiver: address, public amount: u64) -> (Token, Final) {
        let difference: u64 = sender.amount - amount;
        let remaining: Token = Token {
            owner: sender.owner,
            amount: difference,
        };
        return (remaining, final {
            let current: u64 = Mapping::get_or_use(account, receiver, 0u64);
            Mapping::set(account, receiver, current + amount);
        });
    }

    // Convert public tokens to private: debits the caller's public `account`
    // balance on-chain and produces a new Token record for the receiver.
    fn public_to_private(public receiver: address, public amount: u64) -> (Token, Final) {
        let transferred: Token = Token {
            owner: receiver,
            amount: amount,
        };
        let caller = self.caller;
        return (transferred, final {
            let current: u64 = Mapping::get_or_use(account, caller, 0u64);
            Mapping::set(account, caller, current - amount);
        });
    }
}