Kevin  Taylor

Kevin Taylor


Arc: Signature Based Minting with Next.JS

Signature Based Minting with Next.JS


In this guide, we will utilize signature-based minting of NFTs to create a "community-built" NFT collection, where each user mints and owns their own NFT based on specific conditions that we provide.

By the end, we'll have an NFT collection of NFTs that are all animal names, as specified in the animalNames.ts file.

Check out the Demo here:


Using This Repo

  • Create a project using this example by running:
npx thirdweb create --template signature-based-minting

Create your own NFT Collection via the thirdweb dashboard (follow the steps in Setting Up The NFT Collection of this doc if you need more help)

Create an environment variable in a .env.local file with your private key, in the form PRIVATE_KEY=xxx, similarly to the .env.example file provided.

Add the NEXT_PUBLIC_NFT_COLLECTION_ADDRESS environment variable to your .env.local file too, in the form NEXT_PUBLIC_NFT_COLLECTION_ADDRESS=xxx, similarly to the .env.example file provided.

What is Signature Based Minting?

NFT Collections come in different shapes, sizes, and rules.

On one end of the spectrum, an NFT collection can be a set amount of NFTs, and they're all made by one wallet, once they're all claimed/minted, no more NFTs are ever minted in the collection. A popular example of this is the Bored Ape Yacht Club Collection.

On the other end of the spectrum, an NFT collection could also start out with no NFTs! NFTs in this collection could be created by anyone, at any time, and the NFTs could look completely different. This type of collection is a bit less well-known, but demonstrates that NFT collections can be totally different!

Signature-based minting enables a use case that is somewhere between these two ends of the spectrum. What if you didn't want EVERYONE to be able to mint an NFT into your collection, or you only wanted specific types of NFTs to be minted?

Signature-based minting allows you to specify exactly what NFTs you allow to be minted into your NFT collection, by generating a signature for an NFT. This signature can be used by a wallet address that you specify to mint that NFT.

In this guide, we'll grant users signatures to mint NFTs into our collection that follow the format we expect.

In the end, we'll have a community-made collection that only contains NFTs with animal names, by restricting the signatures we provide to only allow NFTs with one of our animal names!

Let's get into it!

Setting Up The NFT Collection

To create an NFT collection, we can use the thirdweb dashboard and create a fully customizable NFT collection in just a few clicks.

Head to and create a new contract on the Polygon Mumbai network. Click Create NFTs and Tokens > NFT Collection.

Give your collection a name and click Deploy now!

Nice! Now we have an NFT collection. Let's set up a project and see how we can start minting some NFTs using the thirdweb SDK.

Setting Up The Project

To get started, we have a ready-made template that includes all the code you need to work with Thirdweb, TypeScript and Next JS available here

Our application is wrapped in a Thirdweb Provider so that we can access Thirdweb anywhere in our application:

import { ChainId, ThirdwebProvider } from "@thirdweb-dev/react";

// This is the chainId your dApp will work on.
const activeChainId = ChainId.Mumbai;

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ThirdwebProvider desiredChainId={activeChainId}>
      <Component {...pageProps} />

Connecting User's Wallets

Over at the home page at index.tsx, we're using the thirdweb React SDK MetaMask Connector so our user can connect their wallet to our website.

import {
} from "@thirdweb-dev/react";

  const address = useAddress(); // Grab the current user's address
  const connectWithMetamask = useMetamask(); // Connect with metamask
  const disconnectWallet = useDisconnect(); // Disconnect from metamask


We've attached these connectWithMetamask and disconnectWallet functions to the onClick to fire when the user clicks the Connect or Disconnect buttons.

You can see an example of how to implement that logic in our index.tsx file

Loading & Displaying NFTs

For our community collection, each NFT is minted by a different user. We're using another thirdweb hook called useNFTCollection to connect to our smart contract and load all of the NFT's in our collection.

// Fetch the NFT collection from thirdweb via it's contract address.
const nftCollection = useNFTCollection(
  // Replace this with your NFT Collection contract address

Once we've loaded them from the smart contract, we can display each NFT to the user.

We'll be using the React SDK's useNFTs to fetch all of the NFTs in our collection.

Fetch All NFTS:

const { data: nfts, isLoading: loadingNfts } = useNFTs(nftCollection);

Now we've got the NFT's loaded, we can display them to the user!

We'll let you decide how best to display your NFTs, but if you're looking for an example, check out the index.tsx file to see how we did it.

We can also see who is the owner of each nft with .owner, and the and metadata.description inside of each NFT!

Creating NFTs with Signature Based Minting

The way that our signature-based minting process works is in 3 steps:


The connected wallet calls a Next JS API Route with three parameters, authorAddress, nftName, and imagePath inside the request body.

The API route runs some checks on the server-side to see if this user and the NFT they are requesting to mint is eligible or not. If the request is eligible, it generates a signature to mint an NFT with a specific set of characteristics.

Once the API function is done processing, it sends the client/user a signature. The user can call mint with this signature to create an NFT with the conditions provided from our server.

The main benefit here is that we have made an environment where us (the owner of the smart contract) can decide what the user can mint into our collection, all programmatically.

API Route

To create an API Route, you'll need to create a file in the /pages/api directory of your project.

On the server-side API route, we can:

  • Run a few checks to see if the requested NFT meets our criteria
  • Generate a signature to mint the NFT if it does.
  • Send the signature back to the client/user if the NFT is eligible.

De-structure the arguments we passed in out of the request body:

const { authorAddress, nftName, imagePath } = JSON.parse(req.body);

Initialize the Thirdweb SDK on the server-side

// Initialize the Thirdweb SDK on the serverside
const sdk = ThirdwebSDK.fromPrivateKey(
  // Your wallet private key (read it in from .env.local file)
  process.env.PRIVATE_KEY as string,

Load the NFT Collection via it's contract address using the SDK

const nftCollection = sdk.getNFTCollection(
  // Replace this with your NFT Collection contract address

Example Check #1 - Is the name of the NFT an animal name?

if (!animalNames.includes(nftName?.toLowerCase())) {
  res.status(400).json({ error: "That's not one of the animals we know!" });

Example Check #2 - Check that this wallet doesn't already own an NFT in this collection

const hasMinted = (await nftCollection.balanceOf(authorAddress)).gt(0);
if (hasMinted) {
  res.status(400).json({ error: "Already minted" });

When we are satisfied with the NFT conditions, we can generate a signature to mint the NFT

// This is to generate the page number based on how many pages have been minted already
const pageNumber = (await nftCollection.totalSupply()).add(1);

// Generate the signature for the page NFT
const signedPayload = await nftCollection.signature.generate({
  to: authorAddress,
  metadata: {
    name: nftName as string,
    image: imagePath as string,
    description: "An awesome animal NFT",
    properties: {
      // Add any properties you want to store on the NFT

Return the signature to the client

// Return back the signedPayload to the client.
  signedPayload: JSON.parse(JSON.stringify(signedPayload)),

If at any point this process fails or the request is not valid, we send back an error response instead of the generated signature.

res.status(500).json({ error: `Server error ${e}` });

Making the API Request on the client

With our API route available, we make fetch requests to this API, and securely run that code on the server-side.

Call the API route on the client

// Make a request to /api/server
const signedPayloadReq = await fetch(`/api/server`, {
  method: "POST",
  body: JSON.stringify({
    authorAddress: address, // Address of the current user
    nftName: nftName,
    imagePath: url,

// Grab the JSON from the response
const json = await signedPayloadReq.json();

Read the signature from the response

const signedPayload = json.signedPayload;

Mint the NFT with the signature

// Now we can call and pass in the signed payload that we received from the server.
const nft = await nftCollection?;

Join our Discord!

For any questions, suggestions, join our discord at

Download Details:

Author: arcglan
Source Code:

License: Apache-2.0 license


What is GEEK

Buddha Community

Arc: Signature Based Minting with Next.JS

NBB: Ad-hoc CLJS Scripting on Node.js


Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.


Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.


Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).


Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
#js {:columns 216, :rows 47}
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
$ ls


Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.


NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.


To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [ :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"


Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink


(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))


Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
   (println "Doing stuff which takes a while")
   (sleep 1000)

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while

Also see API docs.


Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.


See the examples directory for small examples.

Also check out these projects built with nbb:


See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.



  • babashka >= 0.4.0
  • Clojure CLI >=
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: 
License: EPL-1.0

#node #javascript

Eva  Murphy

Eva Murphy


Google analytics Setup with Next JS, React JS using Router Events - 14

In this video, we are going to implement Google Analytics to our Next JS application. Tracking page views of an application is very important.

Google analytics will allow us to track analytics information.

App link:

You can find me on:

#next js #js #react js #react #next #google analytics

Eva  Murphy

Eva Murphy


Laravel API and React Next JS frontend development - 28

In this video, I wanted to touch upon the functionality of adding Chapters inside a Course. The idea was to not think much and start the development and pick up things as they come.

There are places where I get stuck and trying to find answers to it up doing what every developer does - Google and get help. I hope this will help you understand the flow and also how developers debug while doing development.

App url:
Github code links below:
Next JS App:
Laravel API:

You can find me on:

#next js #api #react next js #next #frontend #development

Lilyan  Streich

Lilyan Streich


Next js Tutorial For Beginners

Next js Tutorial For Beginners is the today’s topic. It is no secret that creating single-page applications can be immensely challenging these days. But with the help of some libraries, frameworks, and tools, it is effortless nowadays. React.js is the common frontend libraries among the Front-end developers. Its virtual dom theory makes React faster and gives us the better application performance. Now, one problem is that Single Page Applications are not at all SEO  friendly because it is rendered on the Client side  and not Server side . So when the Search Engine crawlers try to send a request, they cannot get our meta content or description and not even the main content. Search Engines do not care about how your app is architected or whatever ideology was used to adjust and fetch the right material. Their bots are not as smart as using your apps as a real user would. All they care about is that once they send their spiders to crawl and index your site, whatever the server provides on the first request is what gets indexed. In our case, all they get is our div tag with an id and bundled JS file, and we can not index our website correctly. So some how, we need a SSR to tackle this problem and in React js, Next.js is the perfect solution.

#js #react.js #next.js

Hire Dedicated Node.js Developers - Hire Node.js Developers

If you look at the backend technology used by today’s most popular apps there is one thing you would find common among them and that is the use of NodeJS Framework. Yes, the NodeJS framework is that effective and successful.

If you wish to have a strong backend for efficient app performance then have NodeJS at the backend.

WebClues Infotech offers different levels of experienced and expert professionals for your app development needs. So hire a dedicated NodeJS developer from WebClues Infotech with your experience requirement and expertise.

So what are you waiting for? Get your app developed with strong performance parameters from WebClues Infotech

For inquiry click here:

Book Free Interview:

#hire dedicated node.js developers #hire node.js developers #hire top dedicated node.js developers #hire node.js developers in usa & india #hire node js development company #hire the best node.js developers & programmers