<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[ximxim]]></title><description><![CDATA[ximxim]]></description><link>https://blog.commercebuilders.academy</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 11:59:06 GMT</lastBuildDate><atom:link href="https://blog.commercebuilders.academy/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Web3 DAPP powered by Netlify - NFT Avatar]]></title><description><![CDATA[I am excited to share my recent DAPP project in which I explored working with Netlify. This project's goal is to create an NFT collection of wallets with avatars. These avatars can be used by the users to identify themselves to various web3 platforms...]]></description><link>https://blog.commercebuilders.academy/web3-dapp-powered-by-netlify-nft-avatar</link><guid isPermaLink="true">https://blog.commercebuilders.academy/web3-dapp-powered-by-netlify-nft-avatar</guid><category><![CDATA[Netlify]]></category><category><![CDATA[NetlifyHackathon]]></category><dc:creator><![CDATA[Azim Ahmed]]></dc:creator><pubDate>Fri, 25 Feb 2022 15:31:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1645801479931/Bn3I0WTPf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am excited to share my recent DAPP project in which I explored working with Netlify. This project's goal is to create an NFT collection of wallets with avatars. These avatars can be used by the users to identify themselves to various web3 platforms. </p>
<h2 id="heading-tech-stack">Tech Stack</h2>
<p>I used <a target="_blank" href="https://nextjs.org/">NextJs</a> to make the DAPP and <a target="_blank" href="https://www.netlify.com/">Netlify</a> for deployments. Feel free to go through the code in 
 <a target="_blank" href="https://github.com/ximxim/nft-avatar">Github</a> repo or try out the <a target="_blank" href="https://nft-avatar.netlify.app/">DAPP</a>.</p>
<h2 id="heading-how-to-use-the-dapp">How to use the DAPP</h2>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>A crypto wallet like Metamask.</li>
<li>Have a small amount of <a target="_blank" href="https://coinmarketcap.com/currencies/polygon/">MATIC</a> in order to mint your avatar.</li>
</ul>
<h3 id="heading-steps">Steps</h3>
<ul>
<li>Open the <a target="_blank" href="https://nft-avatar.netlify.app/">DAPP</a> in your browser of choice.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645762261337/9z7beVs9v.png" alt="image.png" /></li>
<li>Click on the <code>Connect Wallet</code> button.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645762360960/HEQx6-hx5.gif" alt="Screen Recording 2022-02-24 at 11.11.54 PM.gif" /></li>
<li>Select your wallet of choice.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645762432856/j6sy_Hfdb.gif" alt="Screen Recording 2022-02-24 at 11.12.59 PM.gif" /></li>
<li>Once the wallet is connected, upload an image and fill out the avatar form.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645764046347/ObXceq0Or.gif" alt="Screen Recording 2022-02-24 at 11.17.20 PM.gif" /></li>
<li>Click on the <code>Create NFT Avatar</code> button.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645764107042/qsPoiTj0_.gif" alt="Screen Recording 2022-02-24 at 11.17.20 PM.gif" /></li>
<li>Confirm the transaction.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645764159139/NJiqAD_PG.gif" alt="Screen Recording 2022-02-24 at 11.17.20 PM.gif" /></li>
<li>That's all, you now own a custom NFT avatar.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645764308265/fSMe6tmVe.gif" alt="Screen Recording 2022-02-24 at 11.43.26 PM.gif" /></li>
</ul>
<h2 id="heading-why-netlify">Why Netlify</h2>
<p>There are many reasons why you should pick Netlify over other hosting solutions, here are my top three reasons to pick Netlify for this project. I have used Vercel in my previous projects, so a lot of my decision-making will be compared to Vercel.</p>
<h3 id="heading-1-easy-to-deploy-nextjs">1. Easy to deploy NextJS</h3>
<p>I built this project without Netlify in mind and when it came time to host the project, I was hesitant to deploy to Netlify over Vercel because I thought there would be a considerable amount of work involved. However, that hesitation was unfounded, all I had to do was add Netlify's npm package <code>@netlify/plugin-nextjs</code> and that's it. I was able to start deploying my NextJS app to Netlify.</p>
<pre><code class="lang-shell">yarn add @netlify/plugin-nextjs
</code></pre>
<p>OR</p>
<pre><code class="lang-shell">npm install @netlify/plugin-nextjs
</code></pre>
<h3 id="heading-2-speedy-deploys">2. Speedy deploys</h3>
<p>Netlify deploys are very speedy, initial deployment took a bit longer than I expected. However, the following deployments were very speedy due to Netlify's sophisticated caching mechanism.</p>
<p>While waiting you can play a matching game, I love this small yet personal touch.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645800206525/GMgk4i2ok.png" alt="image.png" /></p>
<h3 id="heading-3-environment-variables-settings">3. Environment variables settings</h3>
<p>Netlify sensitive environment variable policy is a huge win in my books. I failed to find something similar on the Vercel platform. Some of the environment variables are very sensitive in nature and I always wanted to put them behind role-based access which Netlify allows. Also, what if a team member decides to console log one of these sensitive variables by pushing some code, they can bypass that role-based access.</p>
<p>Netlify's sensitive environment variable policy counters these concerns beautifully by allowing project owners to decide whether deploys will need approvals or they just won't use sensitive data.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645800345397/J3mzy08FR.png" alt="image.png" /></p>
<h3 id="heading-there-is-more-to-love">There is more to love</h3>
<p>Netlify's project dashboard is like candy land for me. I see all these others options such as Plugins, Identity, Forms, Graph and many more. I want to build more projects using these other features that I didn't get a chance to work with in this project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645800811264/X2sMFd5oB.png" alt="image.png" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Working with Netlify was very frictionless and I found the <a target="_blank" href="https://docs.netlify.com/">Docs</a> very useful. They have a great support team.</p>
]]></content:encoded></item><item><title><![CDATA[How I made a gasless NFT drop with Javascript only]]></title><description><![CDATA[I am excited to share my recent DAPP project in which I explored meta transactions to allow users to perform blockchain transactions without paying for gas. This single-page DAPP displays a collection of ERC1155 tokens. Each token holds an image of a...]]></description><link>https://blog.commercebuilders.academy/how-i-made-a-gasless-nft-drop-with-javascript-only</link><guid isPermaLink="true">https://blog.commercebuilders.academy/how-i-made-a-gasless-nft-drop-with-javascript-only</guid><category><![CDATA[thirdweb]]></category><category><![CDATA[thirdweb Hackathon]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Azim Ahmed]]></dc:creator><pubDate>Sun, 30 Jan 2022 23:37:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1642776191041/It-qoEpoU.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am excited to share my recent DAPP project in which I explored meta transactions to allow users to perform blockchain transactions without paying for gas. This single-page DAPP displays a collection of ERC1155 tokens. Each token holds an image of a dinosaur and some metadata related to the species etc.</p>
<p><em>Disclaimer: The dinosaurs' information is not accurate at all.</em></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/Wo5uhmdgoVc">https://youtu.be/Wo5uhmdgoVc</a></div>
<h2 id="heading-tech-stack">Tech Stack</h2>
<p>I used <a target="_blank" href="https://nextjs.org/">NextJs</a> to make the DAPP and <a target="_blank" href="https://thirdweb.com/">ThirdWeb</a> handle smart contract logic. Feel free to go through the code in 
 <a target="_blank" href="https://github.com/ximxim/dinosaur-gasless-nft-drop">Github</a> repo or try out the <a target="_blank" href="https://dinosaur-gasless-nft-drop.vercel.app/">Demo</a>.</p>
<h2 id="heading-what-is-thirdweb">What is ThirdWeb?</h2>
<p>ThirdWeb is candy land for a javascript developer who wants to dive into web3 without having to learn Solidity. ThirdWeb provides many typescript-friendly SDKs. They have various modules for unique blockchain purposes. Developers can create a simple NFT drop or create their own DAO or a game. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1642792849315/5kCjTy-ba.gif" alt="Screen Recording 2022-01-21 at 2.18.30 PM.gif" /></p>
<p>The SDKs are very intuitive and continuously evolving to accommodate more and more functionality. Definitely check their documentation out these <a target="_blank" href="https://thirdweb.com/portal">guides</a> and join their <a target="_blank" href="https://discord.com/invite/thirdweb">discord</a>. There are always some interesting conversations taking place that I learn a lot from.</p>
<h2 id="heading-what-are-meta-transactions">What are Meta Transactions?</h2>
<p>Just like metadata is data about data, a meta transaction is a transaction type that the user can sign and execution of that transaction can happen from another wallet. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1642793233936/AmF_VXM7m.png" alt="image.png" /></p>
<p>Here are some resources that can hopefully help understand this concept in-depth: </p>
<p><a target="_blank" href="https://docs.openzeppelin.com/contracts/4.x/api/metatx">OpenZeppeling ERC2771Context</a></p>
<p><a target="_blank" href="https://medium.com/@austin_48503/ethereum-meta-transactions-90ccf0859e84">Medium</a></p>
<p><a target="_blank" href="https://thirdweb.com/portal/guides/setup-gasless-transactions">ThirdWeb Guide</a></p>
<h2 id="heading-setup-thirdweb">Setup ThirdWeb</h2>
<p>In order to start the project, I created a <a target="_blank" href="https://raw.githubusercontent.com/ximxim/dinosaur-gasless-nft-drop/main/scripts/setup-thirdweb.js">script</a> that will create my ThirdWeb project. I chose to work with the <a target="_blank" href="https://thirdweb.com/portal/guides/bundle-collection">Bundle Collection</a> module.</p>
<p><em>Disclaimer: all the steps in the script can also be performed on ThirdWeb's beautiful GUI.</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1642793720183/MzPZ7tb6k1.png" alt="image.png" /></p>
<p>The script starts by creating an instance of ThirdWeb SDK. In the constructor, I pass the private key of my crypto wallet and a provider. The provider is where we get to set which chain we want to work with. I chose to work with Polygon Mumbai testnet and that's what <code>rpcUrl</code> is set to.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> sdk = <span class="hljs-keyword">new</span> ThirdwebSDK(
  <span class="hljs-keyword">new</span> ethers.Wallet(privateKey, ethers.getDefaultProvider(rpcUrl)),
);
</code></pre>
<p>Next, the script creates an app on ThirdWeb if there isn't one already created. The app is basically a project in which you can set up various modules for your purposes.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> app = <span class="hljs-keyword">await</span> sdk.createApp({
  <span class="hljs-attr">name</span>: <span class="hljs-string">'Jurassic Park'</span>,
  <span class="hljs-attr">description</span>: <span class="hljs-string">'When dinosaurs rules the earth'</span>,
});
</code></pre>
<p>Next, the script creates a bundle drop module if there isn't one already created. This module acts as your collection on NFT marketplaces like <a target="_blank" href="https://opensea.io/">OpenSea</a>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> bundleDropModule = <span class="hljs-keyword">await</span> app.deployBundleDropModule({
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Jurassic Park"</span>,
  <span class="hljs-attr">description</span>: <span class="hljs-string">"When dinosaurs rules the earth"</span>,
  <span class="hljs-attr">image</span>: readFileSync(<span class="hljs-string">'scripts/assets/logo.png'</span>),
  <span class="hljs-attr">primarySaleRecipientAddress</span>: ethers.constants.AddressZero,
});
</code></pre>
<p>Next, the script creates all the NFTs in the collection based on the metadata array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> ids = <span class="hljs-keyword">await</span> bundleDrop.createBatch(metadatas);
</code></pre>
<p>Next, the script will update the claim conditions for our NFTs. Simply put, claim conditions are a set of rules that define how many NFTs are in the supply, how many NFTs can be claimed in one transaction, etc. </p>
<p>In my case, I wanted my NFTs to have an unlimited supply, one NFT to be claimed per transaction and the sale to start right away. Hence the script sets the claim condition accordingly.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> claimFactory = bundleDrop.getClaimConditionFactory();
claimFactory.newClaimPhase({ <span class="hljs-attr">startTime</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">maxQuantityPerTransaction</span>: <span class="hljs-number">1</span> });

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> id <span class="hljs-keyword">in</span> ids) {
  <span class="hljs-keyword">await</span> bundleDrop.setClaimCondition(id, claimFactory);
}
</code></pre>
<p>Finally, the script will claim one of each NFT to create a genesis token. If this step isn't performed, the NFT won't show on the market places. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> id <span class="hljs-keyword">in</span> ids) {
  <span class="hljs-keyword">await</span> bundleDrop.claim(id, <span class="hljs-number">1</span>)
}
</code></pre>
<p>That's all, after running the script our smart contracts are all set up and ready to consume. Crazy right? I am still amazed by the simplicity of their SDK.</p>
<h2 id="heading-connect-dapp">Connect DAPP</h2>
<p>In my NextJs app, I used <a target="_blank" href="https://www.npmjs.com/package/web3modal">web3modal</a> to handle the connection to the user's crypto wallet. This library is one of many open source libraries that help with the wallet connection flow of the DAPP. I passed it network information in order to connect to Polygon Mumbai testnet.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">this</span>.web3Modal = <span class="hljs-keyword">new</span> Web3ModalLib({
  network,
  <span class="hljs-attr">cacheProvider</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">providerOptions</span>: {
    <span class="hljs-attr">walletconnect</span>: {
      <span class="hljs-attr">package</span>: WalletConnectProvider,
      <span class="hljs-attr">options</span>: {
        infuraId,
        <span class="hljs-attr">rpc</span>: { [chainId]: rpcUrl },
      },
    },
  },
});
</code></pre>
<p>Once the modal is instantiated, we can trigger connection flow by calling the <code>connect</code> method. On success, it will return us the provider that we can then use to instantiate <a target="_blank" href="https://www.npmjs.com/package/ethers">ethers</a>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> provider = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.web3Modal.connect();
<span class="hljs-built_in">this</span>.ethers = <span class="hljs-keyword">new</span> ethers.providers.Web3Provider(provider <span class="hljs-keyword">as</span> any, <span class="hljs-string">'any'</span>);
</code></pre>
<p>Ethers library will help us get a <a target="_blank" href="https://docs.ethers.io/v5/api/signer/">Signer</a> from the provider and pass it to ThirdWebSdk. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> signer = <span class="hljs-keyword">await</span> Web3ModalService.ethers.getSigner();
<span class="hljs-keyword">const</span> thirdWebSdk = <span class="hljs-keyword">new</span> ThirdwebSDK(signer);
</code></pre>
<p>Now we can allow users to claim the NFT by calling the Bundle Drop module's <a target="_blank" href="https://nftlabs.github.io/nftlabs-sdk-ts/sdk.bundledropmodule.claim.html">claim</a> method.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> <span class="hljs-built_in">module</span> = thirdWebSdk.getBundleDropModule(moduleAddress);
<span class="hljs-keyword">await</span> <span class="hljs-built_in">module</span>.claim(nftId, <span class="hljs-number">1</span>);
</code></pre>
<p>However, the transaction isn't gasless yet. When the user triggers the claimed method, they will be charged a gas fee. Let's set up our gasless transactions next.</p>
<h2 id="heading-oz-defender-set-up">OZ Defender set up</h2>
<p>I followed this very useful <a target="_blank" href="https://thirdweb.com/portal/guides/setup-gasless-transactions">guide</a> to set up an <a target="_blank" href="https://openzeppelin.com/defender/">OpenZeppelin Defender</a>.</p>
<p>Once the OZ Defender is set up, we can copy the webhook URL and pass it to ThirdWebSdk by using the <code>transactionRelayerUrl</code> option.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> signer = <span class="hljs-keyword">await</span> Web3ModalService.ethers.getSigner();
<span class="hljs-keyword">const</span> thirdWebSdk = <span class="hljs-keyword">new</span> ThirdwebSDK(signer, { transactionRelayerUrl });
</code></pre>
<p>That's it, now the claim transactions are gasless.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Working with ThirdWeb was very frictionless and I found the <a target="_blank" href="https://nftlabs.github.io/nftlabs-sdk-ts/sdk.html">SDK API documentation</a> very useful. They have a great support team.</p>
]]></content:encoded></item></channel></rss>