Sui.

Post

Share your knowledge.

Owen.
Owen1466
May 31, 2025
Expert Q&A

Type checking error when using a custom struct as a type parameter in Sui Move's coin::Coin?

Question:

I'm encountering a type checking error in my Sui Move code that I don't understand. Here's a simplified version of my code:

module my_module::mymodule {
    use sui::coin;
    use sui::wallets;

    struct MyCoin has drop {}

    public fun create_coin(): coin::Coin<MyCoin> {
        coin::mint(1000)
    }
}

When I try to compile, I get the following error:

Invalid type parameter instantiation.
Expected type 'phantom type T' but found 'MyCoin'

What am I doing wrong? Why can't I use MyCoin as a type parameter for coin::Coin, and how can I fix this type checking issue?

  • Sui
  • Architecture
4
4
Share
Comments
.

Answers

4
HaGiang.
Jun 1 2025, 03:20

You’re hitting this type checking error because coin::Coin expects T to be a phantom type — meaning it’s only used at the type level and never stored in actual data structures. In your original code, you defined MyCoin as a normal struct without any type parameters or phantom usage. That breaks the expectation of the coin module.

The coin module in Sui is designed to be generic, where the coin type is just a marker — like a label to distinguish one coin from another. That’s why it expects the type to carry no actual data and only exist for typing purposes.

4
Comments
.
harry phan.
May 31 2025, 09:45

You’re attempting to use coin::mint(1000) without properly registering your custom coin type MyCoin. In Sui Move, before you can mint a custom coin, you need to define and register it using the create_currency function.

https://docs.sui.io/references/framework/sui/coin

1
Comments
.
MoonBags.
Jul 23 2025, 16:08

You’re getting the error because sui::coin::Coin requires T to be a phantom type, and your MyCoin struct isn’t marked as such. To use your custom MyCoin as the type for coin::Coin, your struct must:

module my_module::mymodule {
    use sui::coin;

    struct MyCoin has drop, store {} // add `store` because it's often required
    phantom struct PhantomMyCoin has drop, store {}

    public fun create_coin(): coin::Coin<PhantomMyCoin> {
        coin::mint<PhantomMyCoin>(1000)
    }
}
1
Comments
.
0xduckmove.
Jul 23 2025, 16:09

You’re trying to use your custom MyCoin as a type argument for coin::Coin, but Move throws:

Invalid type parameter instantiation. Expected type 'phantom type T' but found 'MyCoin'

What this means in plain terms is: coin::Coin is designed to only accept types that are declared as phantom. You tried to pass in a regular struct, and the compiler said: “Nope, I can’t safely guarantee how this is used in memory.

So, unless your type is declared like this:

phantom struct MyCoin has store, drop {}

…it cannot be used with coin::Coin.

-1
Comments
.

Do you know the answer?

Please log in and share it.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

610Posts1335Answers
Sui.X.Peera.

Earn Your Share of 1000 Sui

Gain Reputation Points & Get Rewards for Helping the Sui Community Grow.

Reward CampaignJuly