How I Created a Crowdfunding Platform with Web3 & Micro-Frontends
Tags: webdev, typescript, webpack, web3
Published: 2021-12-19 06:32:06

Over the past few months, I was learning about **Micro-Frontend** & **Web3 Technologies**. As the best way to learn is to _try things hands-on_, so I built up a small side-project to test out my understanding of the topics.

The aim of the project was to create a **Crowdfunding** Platform based on the **Ethereum Blockchain** utilizing **Micro-Frontend Architecture**

You can dive into the source code here

{% github https://github.com/ruppysuppy/Crypto-Crowdfund no-readme %}

And the website here: https://crypto-crowdfund.web.app/

**NOTE:** You need a **[MetaMask](https://metamask.io/) Wallet** to interact with the blockchain

# Smart Contract

You can interact with **Ethereum Blockchain** using **Smart Contracts**, so let's create one as per our requirement. The **Contracts** used in the project is available [here](https://github.com/ruppysuppy/Crypto-Crowdfund/blob/main/packages/smart-contract/contracts/Campaign.sol)

Making changes to a deployed **Smart Contracts** is not possible, and you have to _re-deploy_ the contract, which costs **Ethereum coins** as **Gas Fee**. So it is essential that you [extensively test](https://github.com/ruppysuppy/Crypto-Crowdfund/tree/main/packages/smart-contract/test) the contract before deploying

Since storing data in the **Smart Contracts** incur **Gas Fee** too, only the essential data, such as the **Campaign Manager**, the **Votes for a Transaction Request**, etc are stored on the **Blockchain**.

### Potential Improvements

1. Split the **Campaign Factory** and the **Campaign** into separate files containing only the given **Smart Contract**
2. Add the **Manager functionality** as a separate **Smart Contract** and add it to the **Campaign** using inheritance

# Micro-Frontend

With the **Smart Contract** out of the way, let's focus on the **Micro-Frontend**

![Let's Focus](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ja1v7dql1s8ilsps3w9.gif)

**Micro-Frontend architecture** is a design approach in which a Frontend app is decomposed into **individual, independent “micro-apps”** working _loosely together_.

> Was **Micro-Frontend Architecture** essential for this project?

The answer to that is a definite **NO**. Then why did I use it? _Just to put what I learned to practice_. **Micro-Frontend Architecture** is useful only when working with _large teams_, _where the role of each team is to work on only a small sub-section of the project_

The **Micro-Frontend** was implemented using **Webpack's Module Federation Plugin**. If you want to learn how to implement **Micro-Frontends** from scratch, you are highly encouraged to check out [this article](https://dev.to/ruppysuppy/micro-frontends-the-next-gen-way-to-build-web-apps-16da)

The **Webpack** config for each of the sub-apps and the container follow the same method. 

1. Make a `common config` file with the shared **config** for **dev** & **prod** build, for example:
    ```js
    // imports ...

    module.exports = {
      // all shared config ...
    };
    ```
2. Make a `dev config` and merge it with the `common config`
    ```js
    const { merge } = require('webpack-merge');
    // other imports ...

    const devConfig = {
        // all development config ...
      },
    };

    module.exports = merge(commonConfig, devConfig);
    ```
3. Finally make a `prod config` and merge it with the `common config`
    ```js
    const { merge } = require('webpack-merge');
    // other imports ...

    const prodConfig = {
        // all production config ...
      },
    };

    module.exports = merge(commonConfig, prodConfig);
    ```

You can check out all the configuration files [here](https://github.com/ruppysuppy/Crypto-Crowdfund/search?l=JavaScript&q=webpack)

**NOTE:** In the project all the **sub-apps** use **React**, but you can very well use any other _library_ or _framework_ in any of them

## Marketing

Let's start with the simplest **sub-app**, the [Marketing sub-app](https://github.com/ruppysuppy/Crypto-Crowdfund/tree/main/packages/marketing) is only responsible for rendering the _home_, _about_, _faq_, _terms-and-conditions_, _privacy-policy_, and _disclaimer_ pages, and doesn't have much functionality apart from this.

Just as the **Micro-Frontend sub-apps** should only expose generic functions to avoid _library_ or _framework_ dependency between **sub-apps** and the **container**, the **Marketing sub-apps** exposes a `mount` function which takes simple objects as _params_. It has the following signature:

```ts
type Mount = (
  mountPoint: HTMLElement,
  {
    defaultHistory?: History | MemoryHistory;
    initialPath?: string;
    isAuthenticated?: boolean;
    routes: {
      HOME: string;
      ABOUT: string;
      FAQ: string;
      TERMS_AND_CONDITIONS: string;
      PRIVACY_POLICY: string;
      DISCLAIMER: string;
      CAMPAIGNS: string;
      SIGN_IN: string;
    };
    onNavigate?: ({ pathname: string }) => void;,
  },
) => {
    onParentNavigate: ({ pathname: string }) => void
  }
```

Using the `mount` function, the container can mount the **sub-app** as per requirement. `defaultHistory`, `onNavigate` and `onParentNavigate` are used to keep both the container and the **sub-app** in sync and avoid some nasty bugs.

## Auth

Next up is the [Auth sub-app](https://github.com/ruppysuppy/Crypto-Crowdfund/tree/main/packages/auth). It uses **Firebase** authentication to **sign-in** and **sign-up** users and grants them the required permissions. 

It works similarly as the **Marketing sub-app**, by exposing the `mount` function with a similar set of _params_ and handling the _sign-in_ and _sign-up_ pages 

### Potential Improvements

- Use a method to **sign-in** only using the [MetaMask](https://metamask.io/) account, removing the need to **sign-in** in two places to get full access to the application

## Blockchain

Finally, we are at the most difficult to understand **sub-app** of all, the [Blockchain sub-app](https://github.com/ruppysuppy/Crypto-Crowdfund/tree/main/packages/blockchain) is the meat of the project, enabling users to interact with the **backend** & the **blockchain** (to interact with the **blockchain**, you need a [MetaMask](https://metamask.io/) extension on your browser). 

It handles the _account_, _campaign_, _campaigns_ and _create-campaign_ pages.

As mentioned previously, _only the essential data is stored on the contracts_, saving the rest on **Cloud Firestore**. The data from the campaigns are fetched from the addresses residing on the **Blockchain**, and then data from **Firestore** is merged to generate the complete data for a given **Campaign**. Only the creator of the **Campaign** can modify the data on **Firestore** or create **Transaction Request** to spend the available funds, which the Contributors can approve.

### Potential Improvements

- Using _image uploads_ in place of _add url to image_ for both the cover image and the user profile picture (skipped it as the main focus was on integrating **web3** & **micro-frontend**)

## Container

The [Container](https://github.com/ruppysuppy/Crypto-Crowdfund/tree/main/packages/container) is responsible for _condensing all the **sub-apps** into a single application_ and _controlling what is displayed on the screen_.

### Potential Improvements

- Improvised **UI/UX**

# Wrapping Up

It's finally over...

![Relief](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qmw8ndm93q9ytu13kfh.gif)

This article presented a _brief overview_ of the project, you can always dive into the **source code** and _check out the project line by line_

{% github https://github.com/ruppysuppy/Crypto-Crowdfund no-readme %}

**Happy Developing!**

Finding **personal finance** too intimidating? Checkout my **Instagram** to become a [**Dollar Ninja**](https://www.instagram.com/the.dollar.ninja/)

# Thanks for reading

Need a **Top Rated Front-End Development Freelancer** to chop away your development woes? Contact me on [Upwork](https://www.upwork.com/o/profiles/users/~01c12e516ee1d35044/)

Want to see what I am working on? Check out my [Personal Website](https://tapajyoti-bose.vercel.app) and [GitHub](https://github.com/ruppysuppy)

Want to connect? Reach out to me on [LinkedIn](https://www.linkedin.com/in/tapajyoti-bose/)

I am a freelancer who will start off as a **Digital Nomad** in mid-2022. Want to catch the journey? Follow me on [Instagram](https://www.instagram.com/tapajyotib/)

Follow my blogs for **Weekly new Tidbits** on [Dev](https://dev.to/ruppysuppy)

**FAQ**

These are a few commonly asked questions I get. So, I hope this **FAQ** section solves your issues.

1. **I am a beginner, how should I learn Front-End Web Dev?**
   Look into the following articles:

    1. [Front End Development Roadmap](https://dev.to/ruppysuppy/front-end-developer-roadmap-zero-to-hero-4pkf)
    2. [Front End Project Ideas](https://dev.to/ruppysuppy/5-projects-to-master-front-end-development-57p)

2. **Would you mentor me?**
   Sorry, I am already under a lot of workload and would not have the time to mentor anyone.

3. **Would you like to collaborate on our site?**
   As mentioned in the _previous question_, I am in a time crunch, so I would have to pass on such opportunities.