Skip to main content

Command Palette

Search for a command to run...

SuperFluid Tutorial - Subscriptions

Build and deploy a Buy Me A Coffee like dApp using SuperFluid Subscriptions.

Updated
โ€ข11 min read
SuperFluid Tutorial - Subscriptions
A

Blockchain Developer | Web3 | DeFi

Introduction

Meet Sebastian. He is a Music Producer and a YouTube content creator who makes videos about Music Production. Recently, he decided to monetize his content through platforms like Batreon and Buy Me A Toffee. However, he's not too keen on parting with 10% of his hard-earned money to a platform or having to wait for days to withdraw his earnings.

That's when he meets Atharva at a football screening. Atharva, a Blockchain Developer and a fellow music enthusiast strikes up a conversation with Sebastian. As they chat, the topic of record labels exploiting artists by snatching a significant chunk of their earnings arises. Sebastian seizes the moment to share his own experiences with platforms like Batreon and Buy Me A Toffee, expressing his desire to find an alternative platform with minimal fees and transparent payout methods. This is how the conversation unfolds-

What is Money Streaming?

Sebastian: You know, Atharva, these record labels are just ripping off artists with their hefty cuts. Even I am looking for a platform with minimal fees and transparent payout methods.

Atharva: Absolutely, Seb! That's why I'm all about decentralized solutions. I've got the perfect solution for you, so you won't have to stress over transaction fees and delayed payments. With this, you can receive payments every second and withdraw them instantly, all with a very minimal fee.

Sebastian: Really? Tell me more about it!

Atharva: It's called Money Streaming, it is a way of sending or receiving money continuously over time instead of all at once. It's like getting a small part of your regular paycheck every second instead of once a month.

Sebastian: So you are saying - if someone wants to support my content for say $20 per month, instead of paying the whole amount upfront, they can split it into smaller daily payments, which would be around 66 cents per day!? That sounds like a fantastic deal for both my audience and me! It's a win-win situation where my fans can enjoy my content continuously, and I receive a steady stream of income. But it must be difficult to implement right?

SuperFluid Subscriptions

Atharva: You won't believe it! SuperFluid is the absolute pioneer of Money Streaming, and they just rolled out this fantastic feature called SuperFluid Subscriptions. It's like stepping into a whole new dimension for content creators like you who want to monetize your work through money streaming! With SuperFluid Subscriptions, you can offer your fans the option to pay those tiny daily amounts, making it super easy for them to support you continuously. Let's head to my office and build you a super cool website, it shouldn't take more than an hour.

Sebastian: Hold up, Atharva! Are you serious? Do you mean to tell me that you can actually build a Blockchain-based website with all these sophisticated features in just one hour?

Atharva: Absolutely! It might sound complicated but SuperFluid has made it super easy for developers to integrate Money Streaming into your website with their SDKs (Software Development Kits) providing all the necessary tools to make the process very easy.

Prerequisites

๐Ÿ’ก
You can get the code repository and assets from here

Sebastian: This sounds very very interesting, do you mind walking me through the process as we build? How about we start with the skills one must have to start building with SuperFluild?

Atharva: Anyone with a basic knowledge of React, Blockchain Development and Money Streaming can follow along. You can refer to SuperFluid docs to learn about Money Streaming.

Tools and Libraries

Sebastian: What are the tools and libraries we are going to use to build our website?

Atharva: We are going to use -

Designing our Website

Atharva: How do you want your website to look?

Sebastian: I am seeking something minimal, something comprising of only two tones: black and white maybe?

A couple of Iterations and galloons of coffee later...

Sebastian: This looks perfect! Let's call it Brew Me A Latte

Figma File

Setup

Creating a Project

Atharva: First we need to set up our React Project with Vite so we can start building.

npm create vite@latest

Give the Project a name, select React as the framework and TypeScript as the variant. It should look something like this:

Now navigate to the project directory and install the dependencies by typing the following command in the terminal:

  cd brew-me-a-latte
  npm install

Setting up Tailwind for Vite

To know more about using Tailwind with Vite refer to Tailwind Docs.

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Replace the content of your tailwind.config.js file with the following code:

/** tailwind.config.js */
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Now, run npm run dev in your terminal and then open the link given in your terminal, your browser page should look something like this:

Replace the contents of App.css file with the following code:

/* App.css */
/* Importing Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Antonio&display=swap');

/* Tailwind CSS */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Font We Will be using in our project*/
* {
  font-family: 'Antonio', sans-serif;
}
๐Ÿ’ก
Download the images folder from here and save it inside your publicfolder

Getting rid of unwanted files

In this project, we won't need some of the files that Vite has provided, so we can get rid of them. You can delete the index.css file from your src folder. As a result, your src directory will look something like this:

You can remove the index.css dependency from your main.tsx file. Once you do that your main.tsx file should look something like this:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

Installing Libraries

Now that we have set up our project and made the necessary changes, we can now import the required libraries.

Installing SuperFluid Widget and Tokens

npm install --save @superfluid-finance/widget wagmi @superfluid-finance/tokenlist

Installing Web3Modal

npm install @web3modal/ethereum @web3modal/react wagmi viem

Creating our Widget

Sebastian: Woah! Setting up the project was easier than I thought. I expected to be surrounded by 10 terminals, running commands like a hacker. But it's simply a matter of reading the docs and copy-pasting the commands!

Atharva: Absolutely! We are now going to build our checkout widget. Creating a widget and adding functionalities from scratch would have been a very difficult task. But thanks to SuperFluid and their No Code SuperFluid Widget Builder, we can create a highly customizable widget within minutes and that too without writing a single line of code.

Sebastian: Really!? And how do we do that?

Atharva: It's a simple 3 step process

Step 1 - head over to No Code SuperFluid Widget Builder and add your Product Details. Want to support multiple Super Tokens? No worries! You can easily add multiple Payment Options to your widget.

Step 2 - Feel free to customize the UI as you wish, ensuring it seamlessly fits into your website. This way, it will perfectly blend in with the rest of your design. You can add your own custom colours, fonts, and even an image to make it uniquely yours.

Sebastian: Since our website is minimal, I think we should use the Black and White colour combination. We should also add a super cool logo to it.

Atharva: Looks sick!

Step 3: Download the JSON file, rename it as widgetProps.json, and save it inside src folder for now. Later when we create a components folder we will move it inside that directory.

Sebastian: I can imagine how long it would have taken to build it from scratch adding so many payment options!

Setting up Web3Modal

Sebastian: Oh, I have a question! How does our web2-based website interact with our Blockchain Wallet?

Atharva: This is where Web3Modal comes to the rescue. It is a popular javascript library that simplifies the process of integrating multiple blockchain wallets into your decentralized applications (dApps). It provides users with an easier and more consistent way of connecting their wallets to web3 applications.

Sebastian: Amazing! So how can we implement this feature on our website?

Atharva: First you need to sign-up to Wallet Connect Cloud, and create a project. Then, obtain the ProjectId and keep it safe somewhere, as we will be using it later on our website.

You can learn more about Web3Modal here.

Getting your hands dirty

Atharva: Finally now that we are all set up, we can start to write our code. Copy the following code into your App.tsx file:

๐Ÿ’ก
Don't worry if you get an error in the importing components section, we'll be dealing with it in the next step.
// App.tsx
import './App.css'

// Importing components
import { Navbar } from './components/Navbar'
import { Hero } from './components/Hero'

function App() {
return (
    <div id='App'>
      <Navbar />
      <div className="flex justify-center mt-10">
        <Hero />
      </div>
    </div>
  )
}

export default App

Creating Components

In the src directory, go ahead and create a new folder named components. Inside this components folder, add two files: Navbar.tsx and Hero.tsx.

๐Ÿ’ก
Remember saving the widgetProps.json file in the src directory? You can now move it here.

Navbar Component

Paste the following code in your Navbar.tsx file. This deals with the Navbar section of our project.

export const Navbar = () => {
    return (
        <div className="navbar-container flex justify-between text-black border-b-[0.1px] border-yellow  ">
            <div className="logo-container ml-10 my-5">
                <h1 className="text-3xl font-logoTitle font-bold">Brew Me A Latte</h1>
            </div>
        </div>
    )
}

Hero Component

Paste the following code in your Hero.tsx file. You can follow the comments to know what each part of the code is doing.

๐Ÿ’ก
Remember the Web3Modal Project Id we saved earlier? Paste it inside the projectId variable below
// Importing Widget Details
import widgetProps from "./widgetProps.json";

// *** IMPORTING WEB3 LIBRARIES ***

// ** SUPERFLUID LIBRARIES **

// 1. Import SuperFluid Tokens
import superTokenList from "@superfluid-finance/tokenlist";

// 2. Import SuperFluid Widget
import SuperfluidWidget, {
  EventListeners,
  supportedNetworks,
} from "@superfluid-finance/widget";

// 3. Import Web3Modal Library
import {
  EthereumClient,
  w3mConnectors,
  w3mProvider,
} from "@web3modal/ethereum";
import { useWeb3Modal, Web3Modal } from "@web3modal/react";

// 4. Import useMemo hook from react
import { useMemo } from "react";

// 5. Import Wagmi hooks
import { configureChains, createConfig, WagmiConfig } from "wagmi";

// Paste Your ProjectId here
const projectId = "<Enter Your Project Id>";

// Integrating Web3 Modal
const { publicClient } = configureChains(supportedNetworks, [
  w3mProvider({ projectId }),
]);

const wagmiConfig = createConfig({
  autoConnect: false,
  connectors: w3mConnectors({
    projectId,
    chains: supportedNetworks,
  }),
  publicClient,
});

const ethereumClient = new EthereumClient(wagmiConfig, supportedNetworks);

export const Hero = () => {
  const { open, isOpen } = useWeb3Modal();
  const walletManager = useMemo(
    () => ({
      open,
      isOpen,
    }),
    [open, isOpen]
  );

  const eventListeners: EventListeners = useMemo(
    () => ({
      onSuccess: () => console.log("onSuccess"),
      onSuccessButtonClick: () => console.log("onSuccessButtonClick"),
    }),
    [],
  );

  return (
    <div className="hero-container h-fit w-5/6 md:w-1/2">
      <div className="banner-container flex justify-center ">
        <img
          src="/images/banner.png"
          className="rounded-t-[40px]"
          alt="Banner Image"
        />
      </div>
      <div className="profile-photo-container flex justify-center relative bottom-[65px]">
        <img
          src="/images/profile-image-round.png"
          className="w-2/6 md:w-[150px] "
          alt=""
        />
      </div>

      <div className="information-container relative bottom-[65px]">
        <div className="flex justify-center">
          <h1 className="text-3xl font-logoTitle font-bold">
            Sebastian Mercer
          </h1>
        </div>
        <div className="flex justify-center font-semibold mt-2">
          <p className="text-slate-500">Music Producer</p>
        </div>
        <div className="flex justify-center mt-4">
          <WagmiConfig config={wagmiConfig}>
            <SuperfluidWidget className=""
              productDetails={widgetProps.productDetails}
              paymentDetails={widgetProps.paymentDetails}
              tokenList={superTokenList}
              type="dialog"
              theme={widgetProps.theme}
              walletManager={walletManager}
              eventListeners={eventListeners}
            >
              {({ openModal }) => (
                <button className="bg-transperant border-[0.5px] hover:bg-black hover:text-white border-black px-4 py-2 rounded-2xl text-xl" onClick={() => openModal()}>Subscribe</button>
              )}
            </SuperfluidWidget>
          </WagmiConfig>
          <Web3Modal projectId={projectId} ethereumClient={ethereumClient} />
        </div>
        <div className="social-media-handles flex justify-center mt-6">
          <img src="/images/instagram.png" className="w-6" alt="" />
          <img src="/images/youtube-icon.png" className="w-6 ml-4" alt="" />
          <img src="/images/twitch.png" className="w-6 ml-4" alt="" />
          <img src="/images/discord.png" className="w-6 ml-4" alt="" />
        </div>
      </div>
    </div>
  );
};
๐Ÿ›‘
If your Web3Modal is not loading, try refreshing the page or terminating the task and running it again.

Deploying Our Website

Sebastian: Is our website ready? How will my audience interact with it?

Atharva: Almost there! Up until now, we've been working in our local environment. Now, it's time to deploy the project to the internet so that anyone from any corner of the world can access it. For this purpose, we'll be using Netlify.

Sebastian: Oh, so all we need to do is upload our project folder to Netlify and deploy it?

Atharva: Our current build is not optimized for the web, to improve its performance we will first have to deploy it for production. We can do it easily by typing npx vite build in the command line.

Now, you should see a dist folder in your directory. Proceed to Netlify, click on "Deploy Manually," and then upload the dist folder. In a couple of minutes, our website should be live!

Conclusion

Sebastian: Woahhh! Thanks a lot, Atharva. This is exactly what I was looking for. Now my audience can support my work at a very convenient cost. And I won't have to give away a part of my earnings to a centralized platform! What's next now?

Atharva: Next, we will be creating a dashboard where you can keep track of all the people streaming money to you.