# Token Factory

The Token Factory allows you to create your own native denoms, as recognised by the Cosmos SDK Bank Module.&#x20;

This allows your protocol to issue its own token, without needing to support the CW20 standard. It means that all tokens on the Kujira network are compatible as gas-fee payments, and can be collected as protocol revenue and distributed to KUJI stakers.&#x20;

### CLI

Create a denom

```
kujirad tx denom create-denom mydenom
```

Mint it

```
kujirad tx denom mint 10000factory/kujira12345/mydenom kujira123...
```

and Burn it

```
kujirad tx denom burn 10000factory/kujira12345/mydenom 
```

### CosmWASM Bindings

These commands can also be issued via your smart contracts. Please refer to the bindings published in kujira-rs:&#x20;

{% embed url="<https://docs.rs/kujira/0.7.5/kujira/msg/enum.KujiraMsg.html>" %}

#### Creation

In order for the contract to be able to mint and burn a denom, it will need to be created by the contract itself, often upon instantation:&#x20;

```rust
use kujira::msg::{DenomMsg, KujiraMsg};

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
    deps: DepsMut<KujiraQuery>,
    env: Env,
    _info: MessageInfo,
    msg: InstantiateMsg,
) -> Result<Response<KujiraMsg>, ContractError> {
    let addr = env.contract.address;
    let denom = format!("factory/{addr}/{denom}");
    let config = Config::new(msg.owner, denom);
    
    CONFIG.save(deps.storage, &config)?;
    Ok(Response::default()
        .add_message(DenomMsg::Create {
            subdenom: msg.denom,
        }))
}
```

#### Minting & Burning

Now your contract is the owner of the denom, we can mint and burn tokens. Here is an example contract whose purpose is to provide a permissioned list of addresses that can mint and burn, instead of just the admin:

```rust
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut<KujiraQuery>,
    _env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response<KujiraMsg>, ContractError> {
    let mut c = CONFIG.load(deps.storage)?;
    match msg {
        ExecuteMsg::Burn {} => {
            let amt = amount(&c.denom, info.funds)?;
            c.validate_permitted(info.sender)?;

            Ok(Response::default()
                .add_attributes(vec![attr("action", "burn"), attr("amount", amt)])
                .add_message(CosmosMsg::Custom(KujiraMsg::Denom(DenomMsg::Burn {
                    denom: c.denom,
                    amount: amt,
                }))))
        }
        ExecuteMsg::Mint { amount, recipient } => {
            c.validate_permitted(info.sender)?;
            Ok(Response::default()
                .add_attributes(vec![attr("action", "mint"), attr("amount", amount)])
                .add_message(CosmosMsg::Custom(KujiraMsg::Denom(DenomMsg::Mint {
                    denom: c.denom,
                    amount,
                    recipient,
                }))))
        }
        ExecuteMsg::Permit { address } => {
            c.validate_owner(info.sender)?;
            c.permit(address.clone());
            CONFIG.save(deps.storage, &c)?;
            Ok(Response::default()
                .add_attributes(vec![attr("action", "permit"), attr("address", address)]))
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kujira.app/developers/smart-contracts/token-factory.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
