---
# System prepended metadata

title: Manta Asset Design

---


# Manta Asset Design

## Design Goal

The general design goal is to create an unified interface for `pallet-manta-pay`. In principle, `pallet-manta-pay` should support the following kind of assets:

1. Native asset from the relay-chain (e.g. DOT, KSM)
2. Native asset from other parachain (e.g. ACA, KAR)
3. Non-Native asset from other parachain (e.g. KUSD) (TODO: we may need to think about ERC20 tokens)
4. Native asset of Manta/Calamari (e.g. MA, KMA)
5. Non-native asset from Manta/Calamari (e.g. customized asset defined in Manta/Calamari runtimes' `pallet-asset`)

## Related development

converting a remote asset (`X1` if relay-chain token, `X3` if para-chain token) to local currency id.

e.g. refactor the following code:
```rust
MantaTransactorAdaptor
```

## Draft CurrencyId
Now this is our `CurrencyId` definition.
```rust=
pub enum TokenSymbol {
    // Native token
    MA = 5,
    KMA = 1,
    // Acala tokens
    ACA = 0,
    KAR = 128,
    // Shiden
    SDN = 50,

    // Relaychain Token
    KSM,
    DOT,
}

pub enum CurrencyId {
    Token(TokenSymbol),
}
```

I think this is not a good design.
```rust=
#[derive(TokenInfo)] // we might need to impl a proc-macro TokenInfo.
pub enum TokenSymbol {
    // Native token
    #[decimal = 12, blockchain = "manta"]
    MA = 5,
    #[decimal = 12, blockchain = "calamari"]
    KMA = 1,
    // Acala tokens
    #[decimal = 18, asset_id = 1, blockchain = "acala"]
    ACA = 0,
    #[decimal = 12, asset_id = 2, blockchain = "acala"]
    KAR = 128,
    // Shiden
    #[decimal = 18, asset_id = 3, blockchain = "astar"]
    SDN = 50,

    // Relaychain Token
    #[decimal = 10, asset_id = 4, blockchain = "kusama"]
    KSM,
    #[decimal = 12, asset_id = 5, blockchain = "polkadot"]
    DOT,
}

pub enum CurrencyId {
    /*
    scenario 1: CurrencyId::NativeToken(TokenSymbol::KSM, ChainType::Relaychain)
    scenario 2: CurrencyId::NativeToken(TokenSymbol::KAR, ChainType::Parachain(2000))
    scenario 4: CurrencyId::NativeToken(TokenSymbol::KMA, ChainType::SelfChain)
    */
    NativeToken(TokenSymbol, ChainType), // cover scenario 1, 2, 4
    /*
    scenario 3: CurrencyId::NativeToken(TokenSymbol::KUSD, ChainType::Parachain(2000))
    scenario 5: CurrencyId::NativeToken(TokenSymbol::MUSD, ChainType::SelfChain)
    */
    NonNativeToken(TokenSymbol, ChainType), // cover scenario 3, 5
}

pub enum ChainType {
    Relaychain,
    Parachain(ParaId),
    SelfChain,
}
```

## The process of mint a token

What are the users' steps of minting tokens:

1. mint DOT or KSM
2. mint ACA/KAR [transfer done] 
3. mint KUSD
4. mint Manta Native asset
5. mint Manta non-native asset

As the first step, we can experiment with supporting 4 and 5 first.

#### Questions on impl step 4 and 5:
1. How to tell which is native token or non-native token? Maybe `mint` call have a param like: 
```rust=
pub fn mint(
    origin,
    currency_id: CurrencyId,
    // ...
) {}
```

2. If I mint a non-native token, and use `pallet-assets` to handle non-native tokens, how do I know the relation between `currency id` and `asset id`?
```rust=
pub fn mint(
    origin,
    currency_id: CurrencyId,
    // ...
) {
    // ...
    let asset_id = convert(currency_id)?;
    // ...
}
```