1666767840
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: https://signature-based-minting.thirdweb-example.com/
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.
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!
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 https://thirdweb.com/dashboard 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.
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 https://github.com/thirdweb-example/next-typescript-starter
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} />
</ThirdwebProvider>
);
}
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 {
useAddress,
useDisconnect,
useMetamask,
useNFTCollection,
} 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
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
process.env.NEXT_PUBLIC_NFT_COLLECTION_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 metadata.name
and metadata.description
inside of each NFT!
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.
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:
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,
"mumbai"
);
Load the NFT Collection via it's contract address using the SDK
const nftCollection = sdk.getNFTCollection(
// Replace this with your NFT Collection contract address
"0x000000000000000000000000000000000000000"
);
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!" });
return;
}
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" });
return;
}
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.
res.status(200).json({
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}` });
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 signature.mint and pass in the signed payload that we received from the server.
const nft = await nftCollection?.signature.mint(signedPayload);
For any questions, suggestions, join our discord at https://discord.gg/thirdweb.
Author: arcglan
Source Code: https://github.com/arcglan/arc
License: Apache-2.0 license
1632537859
Not babashka. Node.js babashka!?
Ad-hoc CLJS scripting on Node.js.
Experimental. Please report issues here.
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:
Nbb requires Node.js v12 or newer.
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)'
6
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
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs
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)
body))))
body
binding-pairs)))
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 "https://clojure.org")
(.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 "https://clojure.org")
_ (-> (.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
.
$ time nbb -e '(+ 1 2 3)'
6
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
.
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 [foo.bar :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.
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
ink-demo.cljs
:
(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]
(js/Promise.
(fn [resolve _]
(js/setTimeout resolve ms))))
(defn do-stuff
[]
(p/do!
(println "Doing stuff which takes a while")
(sleep 1000)
1))
(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
3
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:
:syms
.-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.
See this gist on how to convert an nbb script or project to shadow-cljs.
Prequisites:
To build:
bb release
Run bb tasks
for more project-related tasks.
Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb
License: EPL-1.0
#node #javascript
1625674200
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.
Frontend: https://github.com/amitavroy/video-reviews
API: https://github.com/amitavdevzone/video-review-api
App link: https://video-reviews.vercel.app
You can find me on:
Twitter: https://twitter.com/amitavroy7
Discord: https://discord.gg/Em4nuvQk
#next js #js #react js #react #next #google analytics
1625751960
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: https://video-reviews.vercel.app
Github code links below:
Next JS App: https://github.com/amitavroy/video-reviews
Laravel API: https://github.com/amitavdevzone/video-review-api
You can find me on:
Twitter: https://twitter.com/amitavroy7
Discord: https://discord.gg/Em4nuvQk
#next js #api #react next js #next #frontend #development
1599119110
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
1616671994
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: https://www.webcluesinfotech.com/hire-nodejs-developer/
Book Free Interview: https://bit.ly/3dDShFg
#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