# 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)?;
// ...
}
```