# Messages
# `Custom_Asset` Module
## Msg/CreateCustomToken
### Inputs
- Denon : string
- Supply : sdk.Int
- Signer : sdk.AccAddress
### Logic
- Validate req is not empty
- Check if denom alrady exists
- State less checks should already have been done in validate basic , such as denom is valid , supply is valid etc
- Set new Custom Token , where
```go
CustomToken{
denom : msg.Denom
minter : msg.Signer
supply : msg.Supply
}
```
## Msg/FreezeAccount
### Inputs
- Denon : string
- Account : sdk.AccAddress // Account that needs to be frozen
- Signer : sdk.AccAddress
### Logic
- Validate req is not empty
- Get Custom Asset using msg.Denom .
- Check if asset.minter == msg.Signer
- Add a new entry to the FreezeList using msg.Denom and msg.Account
- This can be optimized to accept a list of addresses or a list of denoms
## Msg/UnFreezeAccount
### Inputs
- Denon : string
- Account : sdk.AccAddress // Account that needs to be unfrozen
- Signer : sdk.AccAddress
### Logic
- Validate req is not empty
- Get Custom Asset using msg.Denom .
- Check if asset.minter == msg.Signer
- Remove an entry from the FreezeList using msg.Denom and msg.Account
- This can be optimized to accept a list of addresses or a list of denoms
# `Bank_Wrapper` Module
## MsgSend
- This message overrides the bank/transfer.
- When creating the MsgServer the CustomAsset Keeper was provided.So handler has access to the Custom_Asset keeper , inside the Transfer Function
### Inputs(MsgSend)
- FromAddress : string
- ToAddress : string
- Amount : github_com_cosmos_cosmos_sdk_types.Coins
### Logic
- Note since this function overrides the bank/transfer
- it will be called for custom and non-custom assets.
- the msg type will need to be the same struct as the bank module `banktypes.MsgSend`
- The input message amount is of type sdk.Coins. That means it can contain multiple coins , some might be Custom and some Non-Custom.
- We need to do additional checks only for custom tokens.
- When checking if a sender is found to be frozen for a particular token type , we will remove that token from the list of Coins.
- And then call the sdk.Send in the end. So in effect if a user tries to send multiple coins only the non blocked ones will be sent . The blocked ones will get blocked.
- We can emit a event to let the user know which of their tokens were blocked.
- Also the logic only blocks outgoing tokens , incoming tokens can be blocked very easily by adding one more `and` condition for msg.ToAddress
iterate over msg.Amount
```go
for _,coin := range msg.Amount
if isCustomAsset(ctx,coin.denom) && isFrozen (ctx,coin.denom ,msg.FromAddress ){ // add check here to block incoming if needed
remove coin from msg.Amount
}
```
call bank.Send with msg (where amount has been filtered)