How to create a function for minting tokens?

I am going to add a function into my project used Motoko programming language.
Most of functionalities are completed, except mint function.
Please give me examples or some advice.
Thanks

Hello there, are you using ICRC1/ICRC2?

Any transfers from the minter account you specified would mint new tokens upon creating the token.

The minter account would need to call the function.

There is a minting function example from the [Token transfer] example (Token transfer | Internet Computer).

public shared ({ caller }) func transfer(args : TransferArgs) : async Result.Result<Icrc1Ledger.BlockIndex, Text> {
    Debug.print(
      "Transferring "
      # debug_show (args.amount)
      # " tokens to account"
      # debug_show (args.toAccount)
    );

    let transferArgs : Icrc1Ledger.TransferArg = {
      // can be used to distinguish between transactions
      memo = null;
      // the amount we want to transfer
      amount = args.amount;
      // we want to transfer tokens from the default subaccount of the canister
      from_subaccount : args.minterSubaccount; };
      // if not specified, the default fee for the canister is used
      fee = null;
      // we take the principal and subaccount from the arguments and convert them into an account identifier
      to = args.toAccount;
      // a timestamp indicating when the transaction was created by the caller; if it is not specified by the caller then this is set to the current ICP time
      created_at_time = null;
    };

    try {
      // initiate the transfer
      let transferResult = await Icrc1Ledger.icrc1_transfer(transferArgs);

      // check if the transfer was successfull
      switch (transferResult) {
        case (#Err(transferError)) {
          return #err("Couldn't transfer funds:\n" # debug_show (transferError));
        };
        case (#Ok(blockIndex)) { return #ok blockIndex };
      };
    } catch (error : Error) {
      // catch any errors that might occur during the transfer
      return #err("Reject message: " # Error.message(error));
    };
  };
};

You can refer to this forum post.

Hi jennifertran. Thanks for your help.
I am using ICRC1.
So you mean I can mint tokens using “icrc1_trasfer” function, right?

Yes, you use icrc1_transfer as long as the transfer is coming from and the function is called from the minter account.

But ICRC1.TransferArg doesn’t have “from” :frowning:

type TransferArg = record {
from_subaccount : opt Subaccount;
to : Account;
amount : Tokens;
fee : opt Tokens;
memo : opt blob;
created_at_time: opt Timestamp;
};

1 Like

And also, I need to increase totalsupply of my canister using the “mint” function.

1 Like

Apologies, I misspoke above. You would not need to input the minter account in any from field but only need the minter to call icrc1_transfer.

1 Like

Here’s my mint function.

    let mintingAccount = await IcpLedger.icrc1_minting_account();
    switch (mintingAccount) {
      case (null) {
        return #err ("Minting account does not exist");
      };
      case (?mintingAccount) {
        let transferArgs : IcpLedger.TransferArg = {
          from_subaccount = mintingAccount.subaccount;
          to = { owner = to; subaccount = null };
          amount = amount;
          fee = null;
          memo = null;
          created_at_time = null;
        };
        let result = await IcpLedger.icrc1_transfer(transferArgs);
        switch (result) {
          case (#Ok(blockIndex)) {
            return #ok blockIndex;
          };
          case (#Err(mintError)) {
            return #err("Couldn't mint tokens: " # debug_show (mintError));
          };
        }
      };
    }
  };```
Is it ok?
1 Like

I am not sure the mint function could increase the amount of total supply.
Please check above code and let me know what is wrong.

Have you tried to call icrc1_total_supply? It should update properly.

Yeah.

public shared func getTotalSupply(): async IcpLedger.Tokens {
    return await IcpLedger.icrc1_total_supply();
  };

I can get total supply with the function but don’t know how to update the amount.

The total supply of tokens will be automatically updated.

So you mean, my mint function could increase amount of total supply?
Sorry for asking such this stupid questions :frowning:

Yes, this is correct.

When the minter account calls this mint function that you have created with the icrc1_transfer, it will update the total supply with the number of tokens that you “minted” or transferred from the minter account.

Thanks.
As you can see in my mint function, I defined like this:

let transferArgs : IcpLedger.TransferArg = {
   from_subaccount = mintingAccount.subaccount;
   to = { owner = to; subaccount = null };
   amount = amount;
   fee = null;
   memo = null;
   created_at_time = null;
};

mintingAccount.subaccount can mint tokens?

1 Like

Does your minter account have a subaccount? If not, you can leave that null.

You can check using the command:

dfx canister call name_of_your_icrc1_ledger_canister icrc1_minting_account

1 Like

Thanks for your help.
What’s your Discord ID or Telegram ID?

1 Like

DM me and I can send - though I am more response here!

2 Likes

How can I dm you? :heart_decoration:
I am new to this community.