# Minting

{% embed url="<https://github.com/PolymathNetwork/minting-app>" %}

## :eyes: Overview

This tutorial application allows token owners to issue their security token to whitelisted investors. You may also burn tokens, if needed. You should be able to:

1. Import and Export CSV with investor addresses and balances.
2. Mint tokens to investors.
3. Burn tokens.

## :ledger: Import and Export CSV

The CSV that represents issuance has the following format:

```
address, balance
0x0439...8fj4 1200
0xjf73...hf73 400
```

### :point\_up: Import

```typescript
// Processes imported text into tokenholder objects, then sends blockchain transaction to
// issue tokens to uploaded tokenholders.
const importData = (data) => {
  // Split file content into lines
  data = data.split('\r\n')
    // Trim lines 
    .map(record => record.trim())
    // Remove empty lines
    .filter(record => record.length)
    // Convert string amounts to BigNumber.
    .map(record => {
      let [address, amount] = record.split(',')
      return {address, amount: new BigNumber(amount)}
    })
  asyncAction(dispatch, () => issueTokens(data), 'Issuing tokens')
}
```

### :writing\_hand: Issuance

To issue tokens, simply call the SDK's `token.issuance.issue` method.

```typescript
const issueTokens = async (records) => {
  const q = await token.issuance.issue({issuanceData: records})
  await q.run()
  await new Promise(resolve => setTimeout(resolve, 1000))
  dispatch({type: 'RELOAD_TOKENHOLDERS'})
}
```

### :point\_down: Export

You will have the data needed in state store (i.e., `records`). You simply need to concatenate that data into a CSV file.

```typescript
const exportData = () => {
  const csvContent = records.map(({address, balance}) => {
    return [address, balance].join(',')
  }).join('\r\n')
  console.log('csvContent', csvContent)
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8' })
  FileSaver.saveAs(blob, 'whitelist.csv')
}
```

## :fire: Burning

Burning tokens is as intuitive as specifying the `amount`, `address`, and `reason` for burning in each call.

```typescript
// Async action
const burnTokens = async (amount, from, reason = '') => {
  asyncAction(
    dispatch,
    () => controllerRedeem(amount, from, reason),
    `Burning ${amount} tokens from ${from}`
  )
}

const controllerRedeem = async (amount, from, reason) => {
  reason = web3Utils.numberToHex(reason)
  amount = new BigNumber(amount)
  while (true) {
    // Try to redeem tokens...
    try {
      const q = await token.controller.redeem({ amount, from, reason })
      await q.run()
      dispatch({type: 'RELOAD_TOKENHOLDERS'})
      return
    }
    // ...unless current user is not a controller. In that case, add them as a controller first.
    catch (error) {
      if (error.message.includes('You must be the controller')) {
        console.log(`Add ${walletAddress} as controller`)
        const addControllerQ = await token.controller.modifyController({controller: walletAddress})
        await addControllerQ.run()
      }
      else {
        dispatch({type: 'ERROR', error: error.message})
        return
      }
    }
  }
}
```


---

# 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://developers.polymath.network/developers/tutorials-1/minting.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.
