How to Mint Fungible Tokens in JavaScript Using Agoric
Tags: blockchain, javascript, web3
Published: 2023-09-29 12:34:20

Gone are the days of grappling with rigid, one-size-fits-all blockchain tokens. Traditional tokens often fall short of meeting specific project requirements, stifling innovation. However, custom fungible tokens are poised to transform your development efforts.

By learning how to create custom fungible tokens, you'll have the ability to fine-tune your digital assets to meet specific needs, unlocking a world of limitless opportunities. Whether you're thinking of building a dynamic loyalty program, a decentralized marketplace, or your own digital currency, knowing how to mint fungible tokens is your gateway to success.

Are you ready to dive into blockchain and tokenization in JavaScript? This guide is your pathway to understanding how to mint fungible tokens using Agoric, a state-of-the-art platform for building decentralized applications(dApps).

In this article, we'll not only demystify Agoric as a powerful development tool but also highlight the profound importance of fungible tokens in various scenarios. By the end of this article, you'll be well-equipped with the knowledge to effortlessly create fungible tokens using JavaScript and Agoric.

## Introduction to Agoric
[Agoric](https://agoric.com/) is a powerful blockchain platform that offers developers a wide range of tools and features to build decentralized applications(dApps) with ease using Hardened JavaScript. By leveraging Agoric, developers can create, deploy, and manage smart contracts on their private blockchain or the Agoric Mainnet.

Agoric provides a secure and scalable environment for developing blockchain-based solutions. It combines the strengths of JavaScript and secure smart contract design principles to offer a seamless development experience. Developers opt for Agoric because it simplifies the process of building dApps. With its user-friendly interface and ever-improving documentation, Agoric empowers developers to create sophisticated blockchain applications without extensive knowledge of complex blockchain protocols.

Agoric allows developers to choose between using their private blockchain(on local/virtual machines) or deploying their application on the public Agoric Mainnet. The private blockchain option gives developers full control over their networks, while the Mainnet provides access to a wider network of users and potential collaborators.

## Understanding Fungible Tokens
Fungible tokens are a type of digital asset that holds relative value and can be exchanged on a one-to-one basis. These tokens are built on blockchain technology, making them secure, transparent, and easily transferable. Understanding fungible tokens is essential for developers and businesses looking to create their own custom tokens for various purposes.

Some common examples of fungible tokens are digital currencies like Bitcoin (BTC), Ethereum (ETH), Litecoin, Cardano, Ripple, DOGE, USD Coin, and Tether USD among the endless list. 

Each unit of these cryptocurrencies holds the same value and can be used interchangeably for transactions. This interchangeability is what makes fungible tokens ideal for use in financial systems, supply chain management, and other applications where uniformity and exchangeability are crucial.

## Other Types of Token Standards
Apart from fungible tokens, there are also non-fungible tokens (NFTs), Semi-Fungible Tokens, Wrapped Tokens and Security Tokens. Let's take a closer look at these various token standards and understand how they differ:
+ **Non-Fungible Tokens (NFTs)**: Unlike fungible tokens, NFTs are one-of-a-kind and cannot be exchanged on a like-for-like basis. Each NFT possesses unique attributes and characteristics, making it an excellent choice for representing ownership of digital assets such as art, collectables, or virtual real estate.
+ **Semi-Fungible Tokens**: Combining elements of both fungible and non-fungible tokens, semi-fungible tokens can be divided into smaller units like fungible tokens. However, each unit may have its own distinct properties or attributes, providing versatility in token design.
+ **Wrapped Tokens**: These blockchain assets represent assets from a different blockchain. For example, wrapped Bitcoin (WBTC) represents Bitcoin on the Ethereum blockchain. Wrapped tokens facilitate cross-chain compatibility and enhance liquidity across different blockchain ecosystems.
+ **Security Tokens**: Security tokens represent ownership in underlying assets, such as company shares or real estate properties. These tokens are subject to securities regulations and offer investors specific rights and benefits.

Each token standard serves unique purposes in the blockchain space, offering innovative possibilities for diverse use cases and applications.

## Use Cases of Fungible Tokens
Creating your own fungible token offers a versatile toolkit for businesses and developers, opening doors to a wide array of applications. Here are some common and impactful use cases:
+ **Cryptocurrencies**: Fungible tokens serve as the foundation for creating digital currencies tailored to specific ecosystems or platforms, facilitating seamless transactions.
+ **Loyalty Programs**: Fungible tokens can be employed to construct loyalty points or reward systems, allowing customers to earn and redeem tokens within designated programs.
+ **Supply Chain Management**: Fungible tokens can represent physical assets or products within a supply chain, enhancing traceability, transparency, and operational efficiency.
+ **Tokenized Assets**: Through the tokenization of real-world assets such as real estate, commodities, or securities, fungible tokens enable fractional ownership and heightened liquidity.
+ **Digital Assets**: Fungible tokens have found extensive use as digital assets, encompassing cryptocurrencies, stablecoins, and utility tokens, serving as a medium of exchange or trade within specific ecosystems or exchanges.
+ **Rewards and Loyalty Programs**: Businesses can leverage fungible tokens to design reward systems and loyalty programs, offering users incentives like discounts or exclusive products.
+ **Tokenizing Real-World Assets**: Fungible tokens are instrumental in the digitization of real-world assets, simplifying fractional ownership and enabling smoother transferability and liquidity.
+ **Governance and Voting**: Fungible tokens play a role in decentralized governance, allowing token holders to participate in decision-making processes by voting on proposals.
+ **Crowdfunding and Fundraising**: Startups and projects can raise capital through Initial Coin Offerings (ICOs) or Security Token Offerings (STOs) by creating fungible tokens for investors.

These diverse applications of fungible tokens empower developers to craft tailored solutions that address specific use cases and industries.

## Minting Fungible Tokens in JavaScript Using Agoric
Now that we've explored the concept and applications of fungible tokens, let's roll up our sleeves and dive into the exciting process of creating them. Thankfully, Agoric provides the perfect toolkit for this endeavor, making the creation of your fungible tokens a seamless experience within a JavaScript environment. Let's kickstart this journey by setting up your Agoric environment on your local machine.

### Step 1: Setting up Your Agoric Environment
If you're new to Agoric, the first step is to install the Agoric SDK on your system. You can easily do this by following the official [Agoric Getting Started Guide](https://docs.agoric.com/guides/getting-started/), which provides a step-by-step walkthrough for setting up your Agoric environment.

> Please note that the Agoric SDK is compatible with MacOS, Linux, and Windows Subsystem for Linux (WSL). However, it's important to be aware that there is no native support for Windows 10 or Windows 11.

Once you’ve followed the guide, you should have the Agoric CLI tools installed and you'll be able to run Agoric commands from your terminal.
To ensure everything is set up correctly, you can check the versions of the installed tools with `agoric --version`.

![Your Agoric version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e87fboawdv7b04hqab3.png)

### Step 2: Initialize a New Project
In a new project directory, open a terminal and run the following code:
```bash
agoric init <project name>
cd <project name>
agoric install
agoric start
```

![Initialize and start Agoric Swingset](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1re3nazg7dsph8f4ef8i.png)

This will initialize a new Agoric project in your current working directory, which sets up the basic file structure, installs the necessary dependencies and starts running [Agoric Swingset](https://docs.agoric.com/guides/platform/#swingset)(Agoric VM).

This command will scaffold a new project directory with subdirectories for `/contract`, `/api/`, and `/ui`. Your project directory should have a structure similar to:
```lua
/<project name>
|-- contract/
|-- api/
|-- ui/
|-- ...
```
Now that your environment is ready, let's create a new smart contract for minting fungible tokens.

### Step 3: Creating a New Smart Contract
Creating a smart contract in Agoric involves writing the contract's logic and then deploying it to the Zoe platform. Navigate to `/contract/src/`, you’ll find the `contract.js` file. In this file, you'll write the logic for the fungible token contract.

Here is our logic for minting a fungible token:

```js
// @ts-check
/* global harden */
import '@agoric/zoe/exported.js';
import { AmountMath } from '@agoric/ertp';
import { Far } from '@endo/marshal';

const start = async (zcf) => {
  // Create the internal token mint for our fungible digital asset.
  const zcfMint = await zcf.makeZCFMint('FungibleToken');
  
  // Extract the issuer and brand for our token.
  const { issuer, brand } = zcfMint.getIssuerRecord();

  /** @type {OfferHandler} */
  const mintTokens = (seat) => {
    const amount = AmountMath.make(brand, 1000n); // Mint 1000 tokens.
    zcfMint.mintGains(harden({ FungibleToken: amount }), seat);
    seat.exit();
    return 'Minted 1000 tokens successfully';
  };

  const creatorFacet = Far('creatorFacet', {
    makeInvitation: () => zcf.makeInvitation(mintTokens, 'mint tokens'),
    getFungibleTokenIssuer: () => issuer,
  });

  const publicFacet = Far('publicFacet', {
    getFungibleTokenIssuer: () => issuer,
  });

  return harden({ creatorFacet, publicFacet });
};

harden(start);
export { start };

```

Next we have to update our deploy script in `/contract/deploy.js` to bundle our contract to Zoe.

Here is the logic of the deploy script:
```js
// @ts-check

import * as fs from 'fs/promises';
import '@agoric/zoe/exported.js';
import { makeHelpers } from '@agoric/deploy-script-support';

// This script takes our contract code, installs it on Zoe, and makes
// the installation publicly available. Our backend API script will
// use this installation in a later step.

/**
 * @template T
 * @typedef {import('@endo/eventual-send').ERef<T>} ERef
 */

/**
 * @typedef {object} DeployPowers The special powers that agoric deploy gives us
 * @property {(path: string) => string} pathResolve
 * @property {(bundle: unknown) => any} publishBundle
 * @typedef {object} Board
 * @property {(id: string) => unknown} getValue
 * @property {(value: unknown) => string} getId
 * @property {(value: unknown) => boolean} has
 * @property {() => [string]} ids
 */

/**
 * @param {Promise<{zoe: ERef<ZoeService>, board: ERef<Board>, agoricNames:
 * object, wallet: ERef<object>, faucet: ERef<object>}>} homePromise
 * @param {DeployPowers} endowments
 */
const deployContract = async (homePromise, endowments) => {
  // Your off-chain machine (what we call an ag-solo) starts off with
  // a number of references, some of which are shared objects on chain, and
  // some of which are objects that only exist on your machine.

  const { pathResolve } = endowments;

  const { install } = await makeHelpers(homePromise, endowments);

  const CONTRACT_NAME = 'fungibleToken';
  const { id: INSTALLATION_BOARD_ID } = await install(
    './src/contract.js',
    CONTRACT_NAME,
  );

  // Save the constants somewhere where the UI and api can find it.
  const dappConstants = {
    CONTRACT_NAME,
    INSTALLATION_BOARD_ID,
  };
  const defaultsFolder = pathResolve(`../ui/public/conf`);
  const defaultsFile = pathResolve(
    `../ui/public/conf/installationConstants.js`,
  );
  console.log('writing', defaultsFile);
  const defaultsContents = `\
// GENERATED FROM ${pathResolve('./deploy.js')}
export default ${JSON.stringify(dappConstants, undefined, 2)};
`;
  await fs.mkdir(defaultsFolder, { recursive: true });
  await fs.writeFile(defaultsFile, defaultsContents);
};

export default deployContract;


```

### Step 4: Test and Deploy
After writing your contract, you can also write test cases. To do this, find the `/test` directory in `/contract/src/test` and update the files in the folder to satisfy the test case(s) you want. 

In the case of successful tests, you can proceed to deploy your contract using the following command:
```bash
agoric deploy ./contract/deploy.js
```

![Deploying the smart contract](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c2x1tzjgtujux7i99s8.png)

You can learn more about deploying contracts from the official [Deployment Guide](https://docs.agoric.com/guides/agoric-cli/#agoric-deploy).

### Step 5: Consuming Your Smart Contract
After writing and deploying your smart contract, it's crucial to test its functionality. You can use either of the following ways to test the contract:
+ **Using the REPL**: Agoric provides a [REPL(Read-Eval-Print-Loop)](https://docs.agoric.com/reference/repl/#introduction) which can be accessed in the browser, run the following command in the working directory of your Agoric project:
   ```bash
   agoric open —repl
   ```
   This should launch a REPL in your browser at `localhost:8000` and you’d see a UI similar to this:


![REPL preview in browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9d5f02q0d3b7lay4v7a6.png)

+ **Using a mini dApp client**: For a more user-friendly testing experience, you can build a mini dApp frontend. This dApp can be a simple web application that interacts with the Agoric wallet and allows users to mint tokens, make offers, and interact with the contract. The `/ui` directory in your project is where you can build this frontend.
    
    To interact with a smart contract in a dApp client, you need to deploy an API that connects the smart contract to the dApp via HTTP. You can use the provided `/api/src/handler.js` as a starting point and extend it to handle requests related to your fungible token contract. You can learn more about building an [Agoric dApp](https://docs.agoric.com/guides/dapps/#using-a-dapp).

## Conclusion
In this article, we explored how to mint fungible tokens in JavaScript using Agoric. We discussed the step-by-step guide on minting tokens and provided a detailed explanation of the development process. 

As developers, it is crucial to carefully consider our choices based on our specific needs and goals. Minting fungible tokens using Agoric can offer numerous advantages such as customization, scalability, and security. However, it is essential to evaluate whether Agoric aligns with the requirements of your project and explore alternative solutions if necessary.

Remember, the process of minting fungible tokens is just one aspect of blockchain development. There are countless other opportunities and challenges in this space, visit the [Agoric documentation](https://docs.agoric.com/) and explore more things you can potentially do with this great tool.
You can also join the [Agoric community on Discord](https://agoric.com/discord) and connect with other like-minded developers like yourself - feel free to shoot questions there.