I wrote a mov package in which anyone can mint token (very new to move)
module fungible_tokens::rcoin {
use sui::coin::{Self, Coin, TreasuryCap};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
struct RCOIN has drop {}
/// Register the RCOIN currency to acquire its `TreasuryCap`. Because
/// this is a module initializer, it ensures the currency only gets
/// registered once.
fun init(witness: RCOIN, ctx: &mut TxContext) {
// Get a treasury cap for the coin
let treasury_cap = coin::create_currency<RCOIN>(witness, 2, ctx);
// Make it a share object so that anyone can mint
transfer::share_object(treasury_cap)
}
public entry fun mint(
treasury_cap: &mut TreasuryCap<RCOIN>, amount: u64, recipient: address, ctx: &mut TxContext
) {
coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)
}
}
Now, I want to send the coins I have minted to a different address. Sui transfer only transfers an object/sui gas.
Can someone help me with this?
This is how I was able to resolve it.
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
/// Example coin with a trusted manager responsible for minting/burning (e.g., a stablecoin)
/// By convention, modules defining custom coin types use upper case names, in contrast to
/// ordinary modules, which use camel case.
module fungible_tokens::r6coin {
use sui::coin::{Self, Coin, TreasuryCap};
use sui::transfer;
use sui::pay;
use sui::tx_context::{Self, TxContext};
use std::vector;
/// Name of the coin. By convention, this type has the same name as its parent module
/// and has no fields. The full type of the coin defined by this module will be `COIN<R1COIN>`.
struct R6COIN has drop {}
/// For when empty vector is supplied into join function.
const ENoCoins: u64 = 0;
/// Register the RCOIN currency to acquire its `TreasuryCap`. Because
/// this is a module initializer, it ensures the currency only gets
/// registered once.
fun init(witness: R6COIN, ctx: &mut TxContext) {
// Get a treasury cap for the coin
let coin = coin::create_currency<R6COIN>(witness, 2, ctx);
// Make it a share object so that anyone can mint
transfer::share_object(coin)
}
// public entry fun mint(
// treasury_cap: &mut TreasuryCap<R1COIN>, amount: u64, recipient: address, ctx: &mut TxContext
// ) {
// coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)
// }
public entry fun join_split_transfer<T>(coins: vector<coin::Coin<T>>, amount: u64, recipient: address, ctx: &mut TxContext) {
assert!(vector::length(&coins) > 0, ENoCoins);
let coin = vector::pop_back(&mut coins);
pay::join_vec(&mut coin, coins);
pay::split_and_transfer<T>(&mut coin, amount, recipient, ctx);
transfer::transfer(coin, tx_context::sender(ctx))
}
public entry fun mint(
treasury_cap: &mut TreasuryCap<R6COIN>, amount: u64, recipient: address, ctx: &mut TxContext
) {
coin::mint_and_transfer(treasury_cap, amount, recipient, ctx)
}
}
In this code, look at this part
public entry fun join_split_transfer<T>(coins: vector<coin::Coin<T>>, amount: u64, recipient: address, ctx: &mut TxContext) {
assert!(vector::length(&coins) > 0, ENoCoins);
let coin = vector::pop_back(&mut coins);
pay::join_vec(&mut coin, coins);
pay::split_and_transfer<T>(&mut coin, amount, recipient, ctx);
transfer::transfer(coin, tx_context::sender(ctx))
}
Going line by line
assert!(vector::length(&coins) > 0, ENoCoins);
Here I am saying that there should be more than one coin object passed.Here, I am joining the coin objects
let coin = vector::pop_back(&mut coins);
pay::join_vec(&mut coin, coins);
After joining the coin objects, I am calling SUI function which splits the amount and returns the remaining, the remaining is send back to the address.
pay::split_and_transfer<T>(&mut coin, amount, recipient, ctx);
transfer::transfer(coin, tx_context::sender(ctx))