Behind the Scenes: Creating the AirSwap Member Dashboard App

Table of Contents

  1. Introduction

  2. What is the AirSwap Voter Rewards App?

  3. App Features I Developed

  4. Mentorship

  5. Code Reviews

  6. TypeScript

  7. Wagmi Library

  8. Custom React Components

  9. Variable Naming

  10. Regressions

  11. Launch Day

  12. Putting Apps into Production

  13. Conclusion

Introduction

In this post, I'll share my experience and the key lessons I learned while building the AirSwap Member Dashboard app. This app provides users with the ability to stake AST tokens, vote on proposals that influence the AirSwap protocol, and claim rewards for participating in votes.

As a core contributor to the frontend development of this application, I'll take you through my journey and the valuable insights gained along the way.

What is the AirSwap Member Dashboard App?

AirSwap Voting Rewards app - proposals view
AirSwap Voting Rewards app - proposals view

The Main Functionalities of the App Include:

  1. Users can stake and unstake AST tokens to the staking smart contract.

  2. Users have the ability to vote on proposals that influence the AirSwap protocol.

  3. Users can claim rewards from a pool smart contract.

How it Works: When a user stakes AST tokens, their address gains voting rights on proposals. By voting on proposals, you become eligible to claim rewards from a pool once a month. The more tokens a user has staked, the greater their voting power. These rewards are protocol fees that get collected from swaps made on the AirSwap web app.

App Features I Developed

Staking Modal - this is where users can approve, stake and unstake AST tokens
Staking Modal - this is where users can approve, stake and unstake AST tokens

I built the following major features of the app:

  • Staking Flow: A set of components where the user can approve, stake, and unstake tokens to the AirSwap staking smart contract. GitHub.

  • Wallet connection: The buttons and modals in this feature that allow users to connect and disconnect to the app. GitHub.

There were several other smaller features that I built, such as the accordion component. I won’t go into details about these features in this blog post. However, I plan to write a technical post about how I built the staking modal.

Wallet Connection modal
Wallet Connection modal

Mentorship

Receiving mentorship was a major benefit for me working on this project. Working alongside the co-founder and another experienced developer was great. I was able to get feedback on my code and ask for guidance when needed.

I was exposed to critical pieces of software development, such as CI/CD. I helped with the CI/CD process by creating a .yaml file with GitHub actions. After changes are merged with the main branch, these GitHub actions automatically run a build, deploying the code to production.

Diagram of CI/CD
Diagram of CI/CD

I also learned a lot about caching data in local storage. Caching is a key aspect of frontend development, but it's something that most newer developers probably haven't encountered much.

In this app, we used Zustand, which is a lightweight alternative to Redux. I learned that you can import 'persist,' which is Zustand middleware that saves state changes into local storage. While local storage and caching aren’t exactly the same thing, they share a similar concept.

Code Reviews

Having my code constantly reviewed pushed me to design better solutions. Some of my pull requests (PRs) took weeks to merge due to necessary refactors. These refactors forced me to contemplate the "why" behind my code choices and find more efficient ways of accomplishing tasks.

I asked hundreds of questions, which proved immensely valuable. Mentorship is a two-way street; the mentor benefits from reinforcing their own knowledge and honing their communication skills.

Many new developers may feel hesitant to seek mentorship, fearing they have little to offer in return. This is a misconception. I've had many mentors on my software journey and plan to pay it forward to others someday.

TypeScript

The best way for me to learn is through continuous, repeated exposure to something. While I had been exposed to TypeScript enums and records while working on the AirSwap Web app, the additional practice I gained while working on AirSwap Member Dashboard helped solidify my understanding and finally made it all click.

An enum is a data type with named constant values, ideal for finite options. Before enums, I used type-casted objects. Enums enhance readability and type safety, especially for finite value sets.

In TypeScript, a record defines the structure of an object with specific key-value pairs. Records improve code readability and maintainability compared to type-casted objects.

Here's an example from the repo:

export enum ContractTypes {
  AirSwapToken,
  AirSwapStaking,
  AirSwapPool,
}

type ContractList = { [k in ContractTypes]?: `0x${string}` };

export const contractAddressesByChain: Record<number, ContractList> = {
  1: {
    [ContractTypes.AirSwapToken]: "0x27054b13b1B798B345b591a4d22e6562d47eA75a",
    [ContractTypes.AirSwapStaking]:
      "0x9fc450F9AfE2833Eb44f9A1369Ab3678D3929860",
    [ContractTypes.AirSwapPool]: "0xEEcD248D977Fd4D392915b4AdeF8154BA3aE9c02",
  },
  5: {
    [ContractTypes.AirSwapToken]: "0x1a1ec25DC08e98e5E93F1104B5e5cdD298707d31",
    [ContractTypes.AirSwapStaking]:
      "0x51F372bE64F0612532F28142cECF8F204B272622",
    [ContractTypes.AirSwapPool]: "0xa55CDCe4F6300D57831b2792c45E55a899D8e2a4",
  },
};

This code showcases an enum, ContractTypes, and a record, contractAddressesByChain. Enums define contract types, and the record associates contract addresses with chain IDs. This setup ensures validation and prevents unexpected bugs, a crucial aspect in blockchain applications.

Wagmi Library

Wagmi is a React library of hooks that simplifies EVM blockchain connections. While I had prior experience with this library, working on this app deepened my understanding of its features. Tooling for blockchain connections is becoming increasingly user-friendly.

Although I focused on the frontend, connecting the UI to smart contract functions provided valuable exposure to AirSwap's smart contracts. Reading smart contract functions has been a fantastic way to expand my knowledge of crypto and blockchain.

Variable Naming

Consistent and clear variable names are crucial. Poor naming not only makes it challenging for future contributors but also complicates maintenance for the author. Confusing variable names can lead to unexpected bugs.

This situation arose when I attempted to change the name of a variable that a hook returned. Later, when I used the hook in another part of the code, I had to revert the variable's name back to its original form.

Variable names might seem clear to you when you create them, but if they are not descriptive, they can become a source of confusion later on. Ironically, sometimes I'd ask ChatGPT to review a code snippet, and it would highlight issues with my variable names. I've been making a conscious effort to improve them.

Regressions

In software development, "regression" refers to an undesirable behavior that emerges in an app, which previously worked fine, due to a code update or fix. I hadn't considered this before, but it became evident when we were striving to ensure everything worked correctly for the app's launch. Regressions are particularly common when working under tight deadlines.

Launch Day

Participating in a product launch is a fascinating experience. Users eagerly anticipate a great product, and it's a mix of excitement and mild stress. Fortunately, in our case, it was mostly excitement.

We built this app because AirSwap relied on third-party software for users to stake tokens and claim rewards. When the third-party service announced its shutdown, we had a 65-day deadline to develop and launch our app, bringing this functionality in-house.

Perfection in app development is elusive. In most cases, apps will have some minor cosmetic bugs to address at a minimum. What matters most is that the core features function correctly, and critical bugs are absent. In the lead-up to the launch, we worked diligently to test the core features and ensure that everything operated as intended.

We met the deadline, shipping an MVP of the app, and the community's initial response was overwhelmingly positive!

Putting Apps into Production

Apps in production often reveal overlooked bugs from the development phase. This was also the case with the Member Dashboard app, but fortunately, these issues were manageable. User feedback is invaluable in identifying areas for improvement and addressing any lingering bugs.

Conclusion

These are just some of the lessons I learned while working on the AirSwap Member Dashboard app. Collaborating closely with an experienced developer provided me with insights that are challenging to encapsulate in a single blog post. Witnessing how he built features and organized code felt like completing an entire university course.

Now that the app is live, it's in maintenance mode. I take pride in having my name associated with this product and will continue working on it as a maintainer.

My time at AirSwap over the past five months has been a highlight of my professional journey, and I look forward to building more exciting products in the future!

App: https://dao.airswap.eth.limo/.

Here’s the GitHub: https://github.com/airswap/airswap-voter-rewards.

Subscribe to starrdev
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.