<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohammad Shahbaz Alam</title>
    <description>The latest articles on DEV Community by Mohammad Shahbaz Alam (@shahbaz17).</description>
    <link>https://dev.to/shahbaz17</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F345119%2F952c6650-7c27-46a8-b28d-8e04491edc13.png</url>
      <title>DEV Community: Mohammad Shahbaz Alam</title>
      <link>https://dev.to/shahbaz17</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shahbaz17"/>
    <language>en</language>
    <item>
      <title>Using x402-next with Next.js 16</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Thu, 13 Nov 2025 17:21:29 +0000</pubDate>
      <link>https://dev.to/shahbaz17/using-x402-next-with-nextjs-16-1me1</link>
      <guid>https://dev.to/shahbaz17/using-x402-next-with-nextjs-16-1me1</guid>
      <description>&lt;p&gt;This guide covers how to integrate &lt;code&gt;x402-next&lt;/code&gt; with Next.js 16, which introduces a new middleware architecture. In this version, the traditional &lt;code&gt;middleware.ts&lt;/code&gt; file is replaced by &lt;code&gt;proxy.ts&lt;/code&gt;, requiring a slightly different setup and a minor peer dependency adjustment when installing x402-next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;x402-next&lt;/code&gt; currently lists its &lt;code&gt;peerDependencies&lt;/code&gt; as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"peerDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^15.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a result, you may encounter a &lt;strong&gt;peer dependency warning or error&lt;/strong&gt; when installing it in a Next.js 16 application.&lt;br&gt;
To bypass this, install the package using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;x402-next &lt;span class="nt"&gt;--legacy-peer-deps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
This does not affect functionality — &lt;code&gt;x402-next&lt;/code&gt; works correctly with Next.js 16 when configured with the new &lt;code&gt;proxy.ts&lt;/code&gt; structure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Implementation for Next.js 16
&lt;/h2&gt;

&lt;p&gt;In Next.js 16, you must create a &lt;strong&gt;&lt;code&gt;proxy.ts&lt;/code&gt;&lt;/strong&gt; file at the root of your application.&lt;br&gt;
This file replaces the traditional &lt;code&gt;middleware.ts&lt;/code&gt; entry point and defines your x402 payment middleware.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// proxy.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;paymentMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x402-next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Configure x402 payment middleware&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;paymentMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xYourAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// your receiving wallet address&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/protected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$0.01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// payment amount&lt;/span&gt;
      &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base-sepolia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// network name&lt;/span&gt;
      &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access to protected content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://x402.org/facilitator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Facilitator URL for Base Sepolia&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Define route matching configuration&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/protected/:path*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;paymentMiddleware&lt;/code&gt; function from &lt;strong&gt;x402-next&lt;/strong&gt; protects the specified routes, using your wallet address as the recipient for payments. Each route’s configuration defines the required payment amount, while the facilitator URL specifies which network to use (for example, Base Sepolia or Base mainnet). The &lt;code&gt;matcher&lt;/code&gt; setting determines which routes the middleware intercepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differences from Next.js 15 and Earlier
&lt;/h2&gt;

&lt;p&gt;In Next.js 15 and earlier, middleware was defined inside a &lt;code&gt;middleware.ts&lt;/code&gt; file using a &lt;strong&gt;named export&lt;/strong&gt;.&lt;br&gt;
In Next.js 16, this has been replaced by a &lt;strong&gt;default export&lt;/strong&gt; from &lt;code&gt;proxy.ts&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Export Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Next.js ≤15&lt;/td&gt;
&lt;td&gt;&lt;code&gt;middleware.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;export const middleware = ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js 16&lt;/td&gt;
&lt;td&gt;&lt;code&gt;proxy.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;export default ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Example Project
&lt;/h2&gt;

&lt;p&gt;Check out a live example of this setup at 👉 &lt;a href="https://mdsbzalam.dev" rel="noopener noreferrer"&gt;mdsbzalam.dev&lt;/a&gt;&lt;br&gt;
. I recently rebuilt my personal site using Next.js 16 and wanted to play around with x402’s payment functionality. The idea is simple — visitors can view my resume only after sending $1 USDC on Base Sepolia. It’s a small but fun way to see how x402 can handle microtransactions directly on a website.&lt;/p&gt;

</description>
      <category>x402</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>A Step-by-Step Guide on how to Register a Name on Ethereum Using Web3Auth and Clusters.xyz</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Mon, 05 Aug 2024 05:41:51 +0000</pubDate>
      <link>https://dev.to/shahbaz17/a-step-by-step-guide-on-how-to-register-a-name-on-ethereum-using-web3auth-and-clustersxyz-5820</link>
      <guid>https://dev.to/shahbaz17/a-step-by-step-guide-on-how-to-register-a-name-on-ethereum-using-web3auth-and-clustersxyz-5820</guid>
      <description>&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; and &lt;strong&gt;npm&lt;/strong&gt; installed on your machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; or similar application setup.&lt;/li&gt;
&lt;li&gt;Install required dependencies: &lt;code&gt;@web3auth/modal&lt;/code&gt;, &lt;code&gt;@web3auth/ethereum-provider&lt;/code&gt;, &lt;code&gt;viem&lt;/code&gt;, and &lt;code&gt;clusters&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @web3auth/modal @web3auth/ethereum-provider viem clusters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 1: Import Required Libraries
&lt;/h4&gt;

&lt;p&gt;In your React component, start by importing the necessary libraries and modules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Web3Auth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@web3auth/modal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EthereumPrivateKeyProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@web3auth/ethereum-provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WEB3AUTH_NETWORK&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@web3auth/base&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createWalletClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatUnits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;custom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sepolia&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem/chains&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Clusters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isNameValid&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@clustersxyz/sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RegistrationTransactionData_evm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@clustersxyz/sdk/types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Initialize Web3Auth
&lt;/h4&gt;

&lt;p&gt;Configure the Web3Auth with the client ID and network details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_WEB3AUTH_CLIENT_ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your Web3Auth client ID&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chainConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xaa36a7&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Replace with appropriate chain ID&lt;/span&gt;
  &lt;span class="na"&gt;rpcTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RPC_URL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your RPC url&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ethereum Sepolia Testnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;blockExplorer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://sepolia.etherscan.io&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ETH&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tickerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ethereum&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;privateKeyProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EthereumPrivateKeyProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;chainConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chainConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;web3auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Web3Auth&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;web3AuthNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WEB3AUTH_NETWORK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SAPPHIRE_MAINNET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;privateKeyProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;privateKeyProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Connect to Web3Auth
&lt;/h4&gt;

&lt;p&gt;Establish a connection to Web3Auth after connecting with any of the Social provider provider with the Web3Auth Plug n Play Modal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;w3aProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;web3auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Create Public and Wallet Clients
&lt;/h4&gt;

&lt;p&gt;Set up the public and wallet clients for interacting with the blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publicClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sepolia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w3aProvider&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;walletClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createWalletClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sepolia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w3aProvider&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Ensure you use the correct provider&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 5: Initialize Clusters
&lt;/h4&gt;

&lt;p&gt;Set up Clusters with your API key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clusters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Clusters&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_CLUSTER_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your Clusters API key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6: Check Name Availability
&lt;/h4&gt;

&lt;p&gt;Validate the name and check its availability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desiredName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with the name you want to register&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;registerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isNameValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid name format&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nameAvailability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;clusters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getNameAvailability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;nameAvailability&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAvailable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name already taken!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signerAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;walletClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAddresses&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chainId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11155111&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Sepolia&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;clusters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRegistrationTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signerAddress&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;registrationFee&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;gasToken&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;bridgeFee&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;transactionData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to get registration transaction data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;registrationFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;formatUnits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registrationFee&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bridgeFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;formatUnits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bridgeFee&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decimals&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalFees&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Total Registration fee: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;registrationFee&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nBridge fee: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;bridgeFee&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gasToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transactionDetails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactionData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signerAddress&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactionData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactionData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;walletClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transactionDetails&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;publicClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForTransactionReceipt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transactionStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;clusters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTransactionStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;transactionStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;transactionStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;registrationMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; registered successfully!`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;totalFees&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;This guide outlines how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Initialize &lt;a href="https://web3auth.io" rel="noopener noreferrer"&gt;Web3Auth&lt;/a&gt;&lt;/strong&gt; with the required configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect to Web3Auth&lt;/strong&gt; and obtain the provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create public and wallet clients&lt;/strong&gt; for blockchain interactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialize &lt;a href="https://clusters.xyz" rel="noopener noreferrer"&gt;Clusters&lt;/a&gt;&lt;/strong&gt; with your API key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check name availability&lt;/strong&gt; and register the name if available.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make sure to handle errors and edge cases in a production environment.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>web3auth</category>
      <category>clusters</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Moving from Create-React-App to Vite for Web3Auth Projects</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Fri, 26 Jul 2024 10:25:21 +0000</pubDate>
      <link>https://dev.to/shahbaz17/moving-from-create-react-app-to-vite-for-web3auth-projects-4nce</link>
      <guid>https://dev.to/shahbaz17/moving-from-create-react-app-to-vite-for-web3auth-projects-4nce</guid>
      <description>&lt;p&gt;React has moved away from recommending Create React App as the preferred starting point for new projects. When working with Web3Auth SDKs, you might encounter issues like &lt;a href="https://github.com/Web3Auth/web3auth-web/issues/1854" rel="noopener noreferrer"&gt;@metamask/abi-utils/dist/parsers/bool.js issue&lt;/a&gt;. To avoid such issues, we recommend switching to Vite. Follow the steps below to make the transition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - Remove Create React App
&lt;/h2&gt;

&lt;p&gt;First, uninstall &lt;code&gt;react-scripts&lt;/code&gt; and &lt;code&gt;react-app-rewired&lt;/code&gt; from your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm uninstall react-scripts react-app-rewired
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2 - Install Vite Dependencies
&lt;/h2&gt;

&lt;p&gt;Install the required dependencies for Vite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;vite @vitejs/plugin-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Depending on your specific needs, you can choose different plugins from the official &lt;a href="https://main.vitejs.dev/plugins/" rel="noopener noreferrer"&gt;Vite plugins documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3 - Add &lt;code&gt;vite.config.ts&lt;/code&gt; and Install &lt;code&gt;empty-module&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;empty-module&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; empty-module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Assuming, &lt;code&gt;process&lt;/code&gt; and &lt;code&gt;buffer&lt;/code&gt; is already installed, if not, install those as well.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; buffer process
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, create a &lt;code&gt;vite.config.ts&lt;/code&gt; file at the root of your project with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vitejs/plugin-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://vitejs.dev/config/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
  &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;zlib&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_stream_duplex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_stream_passthrough&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_stream_readable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_stream_writable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_stream_transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;empty-module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;define&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;globalThis&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4 - Move &lt;code&gt;index.html&lt;/code&gt; and Include Polyfills
&lt;/h2&gt;

&lt;p&gt;Create React App uses &lt;code&gt;public/index.html&lt;/code&gt; as the default entry point, while Vite looks for &lt;code&gt;index.html&lt;/code&gt; at the root level. Move your &lt;code&gt;index.html&lt;/code&gt; to the root directory and update the script tag accordingly.&lt;/p&gt;

&lt;p&gt;Also, include the polyfills as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Include these lines for polyfills --&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;buffer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;noscript&amp;gt;&lt;/span&gt;You need to enable JavaScript to run this app.&lt;span class="nt"&gt;&amp;lt;/noscript&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/src/index.tsx"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Optionally, you can rename index.tsx to main.tsx to be consistent with Vite folder structure. --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5 - Create &lt;code&gt;vite-env.d.ts&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;vite-env.d.ts&lt;/code&gt; file inside the &lt;code&gt;src&lt;/code&gt; folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;reference types="vite/client" /&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6 - Update Scripts in &lt;code&gt;package.json&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Replace the existing &lt;code&gt;react-app-rewired&lt;/code&gt; scripts in &lt;code&gt;package.json&lt;/code&gt; with Vite scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc &amp;amp;&amp;amp; vite build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite preview"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7 - Update &lt;code&gt;tsconfig.json&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Update your &lt;code&gt;tsconfig.json&lt;/code&gt; to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowSyntheticDefaultImports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"isolatedModules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-jsx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"dom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"dom.iterable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noEmit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noFallthroughCasesInSwitch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolveJsonModule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ESNext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"vite/client"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling URI Malformed Error
&lt;/h2&gt;

&lt;p&gt;You might encounter &lt;code&gt;Error: URI malformed when running the app&lt;/code&gt;. To fix this, remove all references to &lt;code&gt;%PUBLIC_URL%&lt;/code&gt; in the &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional Steps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Remove &lt;code&gt;config-overrides.js&lt;/code&gt; and &lt;code&gt;react-app-env.d.ts&lt;/code&gt; files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these steps, you should be able to successfully migrate your project from Create React App to Vite, providing you with a faster development experience and a more modern build setup.&lt;/p&gt;

</description>
      <category>vite</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Enhancing Security for Sign-In with Ethereum: Phishing and Replay Attacks</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Mon, 27 May 2024 09:50:14 +0000</pubDate>
      <link>https://dev.to/shahbaz17/enhancing-security-for-sign-in-with-ethereum-phishing-and-replay-attacks-2fe3</link>
      <guid>https://dev.to/shahbaz17/enhancing-security-for-sign-in-with-ethereum-phishing-and-replay-attacks-2fe3</guid>
      <description>&lt;h2&gt;
  
  
  Enhancing Security for Sign-In with Ethereum
&lt;/h2&gt;

&lt;p&gt;As the use of blockchain technology expands, so does the adoption of innovative authentication methods like Sign-In with Ethereum (SIWE). While SIWE offers enhanced privacy and decentralization, it also presents unique security challenges. Two critical threats are phishing and replay attacks. In this blog post, we'll explore these risks and provide practical tips on how to mitigate them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Phishing Attacks
&lt;/h3&gt;

&lt;p&gt;Phishing attacks are deceptive tactics used by attackers to trick users into providing sensitive information or signing messages on malicious sites. Here’s how these attacks work and what you can do to stay safe.&lt;/p&gt;

&lt;h4&gt;
  
  
  Malicious Sites
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Risk&lt;/strong&gt;: Attackers create fake websites that mimic legitimate ones, prompting users to sign in. Once the user signs a message, the attacker can use this information maliciously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Verification&lt;/strong&gt;: Always verify the domain requesting the sign-in. Check the URL carefully to ensure it matches the expected domain. Legitimate sites often use secure (HTTPS) connections, indicated by a padlock icon in the browser's address bar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser Extensions&lt;/strong&gt;: Utilize browser extensions such as MetaMask’s phishing detection, which can help identify and warn against malicious sites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Combating Replay Attacks
&lt;/h3&gt;

&lt;p&gt;Replay attacks involve the reuse of a signed message to authenticate or execute transactions without the user's consent. Here's how these attacks happen and strategies to prevent them.&lt;/p&gt;

&lt;h4&gt;
  
  
  Nonce Usage
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Risk&lt;/strong&gt;: If a signed message lacks a unique identifier, it could be intercepted and reused by an attacker for multiple authentications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Include Nonces&lt;/strong&gt;: Incorporate a unique nonce (a one-time-use number) in each sign-in request. Servers should verify these nonces to ensure that each signed message can only be used once.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Session Management
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Risk&lt;/strong&gt;: Improper session management can allow attackers to reuse valid session tokens or messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unique Session Tokens&lt;/strong&gt;: Generate unique session tokens for each authentication request. These tokens should expire after a set period and be invalidated after use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timestamp Verification&lt;/strong&gt;: Include timestamps in signed messages to ensure they are used within a specific time frame. This limits the window of opportunity for an attacker to reuse a message.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;While Sign-In with Ethereum provides a promising alternative to traditional authentication methods, it’s crucial to address the associated security risks. By being aware of phishing and replay attacks and implementing the recommended mitigations, you can enhance the security of your SIWE implementations and protect users from potential threats. Stay vigilant, educate users, and continuously improve your security practices to safeguard against these evolving threats.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Passport.js for Beginners: A Simple Guide</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Wed, 17 Jan 2024 17:26:33 +0000</pubDate>
      <link>https://dev.to/shahbaz17/understanding-passportjs-for-beginners-a-simple-guide-236l</link>
      <guid>https://dev.to/shahbaz17/understanding-passportjs-for-beginners-a-simple-guide-236l</guid>
      <description>&lt;p&gt;If you're diving into web development, chances are you'll encounter Passport.js, a powerful authentication middleware for Node.js applications. This guide will break down Passport.js into three key components: strategy, middleware, and session handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passport Strategy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is a Strategy?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of a strategy as the answer to the question, "How do you log in and identify the user?" It contains two main parts: the configuration and the handler function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Settings to connect with an external API, if needed.&lt;/li&gt;
&lt;li&gt;Not every strategy requires configuration.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example LocalStrategy configuration&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LocalStrategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;passport-local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;Strategy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LocalStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Validate user credentials and return the local user&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Handler Function:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Executed after a successful login for the specific strategy.&lt;/li&gt;
&lt;li&gt;Takes the login process payload and returns the local user.&lt;/li&gt;
&lt;li&gt;For example, FacebookStrategy deals with tokens and user profiles.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example FacebookStrategy handler function&lt;/span&gt;
&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;clientID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-client-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-client-secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;callbackURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-callback-url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Upsert the user in the database based on the Facebook profile&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Pro Tip: Your app can use multiple strategies, such as local usernames/passwords, "Login with Facebook," or "Login with Google."&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Middleware
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is Middleware?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Middleware is where you apply authentication to your user's experience, consisting of setup, the login flow, and checking if the user is logged in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Initialize and use Passport in your app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;passport.initialize()&lt;/code&gt; creates the passport object on the request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;passport.session()&lt;/code&gt; sets up serialize and deserialize methods.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Setup Passport middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Login Flow:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Set up a login URL for each strategy.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;passport.authenticate('something')&lt;/code&gt; for the internal strategy name.&lt;/li&gt;
&lt;li&gt;Strategies may have a callback endpoint for handling authentication flow.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example login flow for LocalStrategy&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;failureRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  isAuthenticated:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Custom middleware to check if a user is logged in.&lt;/li&gt;
&lt;li&gt;Protect endpoints by ensuring they are authenticated.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Custom middleware to check if a user is authenticated&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Protect an endpoint using isAuthenticated middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/protected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a protected endpoint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Session Handling
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is Session Handling?&lt;/strong&gt;&lt;br&gt;
Handles user sessions, ensuring they stay logged in across requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;deserializeUser&lt;/code&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Called during passport.session().&lt;/li&gt;
&lt;li&gt;Takes a session token (from serializeUser) and returns the local user or false.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example deserializeUser method&lt;/span&gt;
&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deserializeUser&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch the user from the database based on the user ID&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;serializeUser&lt;/code&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Called after the Strategy handler.&lt;/li&gt;
&lt;li&gt;It takes the local user and returns a string stored in the session.&lt;/li&gt;
&lt;li&gt;The string is used in deserializeUser to identify the user in your database.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example serializeUser method&lt;/span&gt;
&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serializeUser&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Store the user ID in the session&lt;/span&gt;
  &lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By understanding these three components, you'll be well-equipped to implement secure authentication in your Node.js applications using Passport.js. Remember to explore the various strategies available to suit your specific authentication needs.&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>webdev</category>
      <category>oauth</category>
      <category>passportjs</category>
    </item>
    <item>
      <title>Efficient React Development: A Deep Dive into Components, Hooks, and Performance Optimization</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Fri, 22 Dec 2023 18:19:14 +0000</pubDate>
      <link>https://dev.to/shahbaz17/efficient-react-development-a-deep-dive-into-components-hooks-and-performance-optimization-29j2</link>
      <guid>https://dev.to/shahbaz17/efficient-react-development-a-deep-dive-into-components-hooks-and-performance-optimization-29j2</guid>
      <description>&lt;p&gt;Welcome to a journey of mastering React development! &lt;br&gt;
In the ever-evolving realm of web development, React has emerged as a powerhouse, enabling developers to create dynamic and scalable user interfaces. In this comprehensive blog, we embark on a deep dive into the core concepts and best practices that form the backbone of efficient React development.&lt;/p&gt;

&lt;p&gt;From understanding the significance of React Fragments to unraveling the mysteries of Hooks, Lists, and State Management, this blog is crafted to equip developers with the insights needed to build robust and performant React applications. We'll explore the nuances of conditional rendering, error handling, and the intricacies of controlled components. All in the form of simple FAQs, we'll delve into advanced topics such as lazy loading, code-splitting, and the art of optimizing performance.&lt;/p&gt;

&lt;p&gt;Whether you're a seasoned React developer looking to refine your skills or a newcomer eager to grasp the fundamentals, this blog has something for everyone. Let's embark on this journey together, unraveling the layers of React intricacies and empowering you to elevate your React development game. Ready to dive in? &lt;/p&gt;

&lt;p&gt;Let's explore the depths of React efficiency!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. What is the purpose of the React.Fragment element?&lt;/strong&gt;&lt;br&gt;
React.Fragment is used to group multiple elements without introducing an additional DOM node, facilitating cleaner code structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Explain the concept of Redux middleware.&lt;/strong&gt;&lt;br&gt;
Redux middleware allows developers to intercept and augment Redux actions before reaching the reducer, useful for handling asynchronous actions and side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. What is the significance of the useLayoutEffect Hook in React?&lt;/strong&gt;&lt;br&gt;
useLayoutEffect is similar to useEffect but fires synchronously after all DOM mutations, making it suitable for tasks requiring accurate measurements or DOM layout manipulation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. How does React handle errors in components?&lt;/strong&gt;&lt;br&gt;
React handles errors using error boundaries, special components that catch JavaScript errors in their child component tree and log them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Explain the concept of the key prop in React lists.&lt;/strong&gt;&lt;br&gt;
The key prop provides a unique identifier to elements in React lists, optimizing updates by helping identify changes, additions, or removals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. What is the purpose of the useCallback Hook in React?&lt;/strong&gt;&lt;br&gt;
The useCallback Hook memoizes a callback function, preventing unnecessary re-creation and optimizing performance when dependencies don't change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. How does React handle conditional rendering?&lt;/strong&gt;&lt;br&gt;
Conditional rendering in React is achieved through conditional statements or ternary operators in JSX, allowing components to render different content based on specified conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. What is the role of the displayName property in React?&lt;/strong&gt;&lt;br&gt;
displayName is an optional property in React that provides a human-readable display name for components, aiding in debugging and making component hierarchies more understandable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Explain the concept of hooks rules in React.&lt;/strong&gt;&lt;br&gt;
Hooks rules include calling them only in functional components and custom Hooks, ensuring consistent order across renders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. What is the significance of the useImperativeHandle Hook?&lt;/strong&gt;&lt;br&gt;
useImperativeHandle customizes the instance value exposed when using React.forwardRef, allowing more control over the child component's API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11. What is the purpose of the contextType property in class components?&lt;/strong&gt;&lt;br&gt;
contextType in class components is used to consume context, providing access to the nearest current value of the context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12. Explain the concept of lazy loading in React.&lt;/strong&gt;&lt;br&gt;
Lazy loading in React involves dynamically loading components or assets only when needed, improving performance by reducing initial page load time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13. What is the significance of the useEffect cleanup function?&lt;/strong&gt;&lt;br&gt;
The useEffect cleanup function performs tasks like clearing intervals or unsubscribing when a component is unmounted or dependencies change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;14. How does React handle state in class components compared to functional components?&lt;/strong&gt;&lt;br&gt;
In class components, state is managed using this.state and this.setState(); in functional components, the useState Hook is used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;15. What is the role of the React.memo function in functional components?&lt;/strong&gt;&lt;br&gt;
React.memo is a higher-order component that memoizes a functional component, preventing unnecessary re-renders when props remain unchanged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;16. Explain the purpose of the useEffect dependency array.&lt;/strong&gt;&lt;br&gt;
The useEffect dependency array specifies dependencies that, when changed, trigger the effect to run, controlling when the effect should re-execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;17. What is the significance of the useRef Hook in React?&lt;/strong&gt;&lt;br&gt;
The useRef Hook creates mutable object references that persist across renders, often used for accessing and interacting with DOM elements imperatively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;18. How does React handle forms in controlled components?&lt;/strong&gt;&lt;br&gt;
React handles forms in controlled components by linking form elements to React state, enabling control and management of the form's data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;19. What is the purpose of the React.PureComponent class in React?&lt;/strong&gt;&lt;br&gt;
React.PureComponent is a base class that optimizes rendering performance by implementing a shallow prop and state comparison in shouldComponentUpdate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;20. Explain the concept of hooks in React.&lt;/strong&gt;&lt;br&gt;
Hooks in React are functions enabling state and other React features in functional components, allowing local component state and side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;21. What is the purpose of the React.StrictMode component?&lt;/strong&gt;&lt;br&gt;
React.StrictMode is a component that provides additional warnings and strict checks during development, helping catch common mistakes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;22. How does React handle routing?&lt;/strong&gt;&lt;br&gt;
React handles routing through libraries like React Router, allowing navigation between different views or components in a single-page application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;23. What is the significance of the dangerouslySetInnerHTML attribute in React?&lt;/strong&gt;&lt;br&gt;
dangerouslySetInnerHTML allows inserting raw HTML content in React, but its usage requires caution due to potential security risks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;24. Explain the concept of controlled components in React.&lt;/strong&gt;&lt;br&gt;
Controlled components in React have their form elements linked to React state, allowing control and management of the form's data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;25. What is the purpose of the useContext Hook in React?&lt;/strong&gt;&lt;br&gt;
The useContext Hook simplifies accessing context values within functional components, eliminating the need for render props.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;26. What is the significance of the shouldComponentUpdate method in React?&lt;/strong&gt;&lt;br&gt;
shouldComponentUpdate in class components optimizes rendering by allowing control over when a component should re-render.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;27. Explain the concept of code-splitting in React.&lt;/strong&gt;&lt;br&gt;
Code-splitting involves breaking down bundled JavaScript into smaller chunks, allowing more efficient loading of components as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;28. How does React handle events?&lt;/strong&gt;&lt;br&gt;
React handles events using synthetic events, providing a consistent interface across different browsers and allowing declarative event handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;29. What is the purpose of the useMemo Hook in React?&lt;/strong&gt;&lt;br&gt;
The useMemo Hook memoizes the result of a function, optimizing performance by avoiding unnecessary recalculations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30. Explain the concept of portals in React.&lt;/strong&gt;&lt;br&gt;
Portals in React allow rendering children components outside the DOM hierarchy of the parent component, providing flexibility in rendering components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;31. What is the purpose of the React.Fragment element?&lt;/strong&gt;&lt;br&gt;
React.Fragment is used to group multiple elements without introducing an additional DOM node, facilitating cleaner code structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;32. Explain the concept of Redux middleware.&lt;/strong&gt;&lt;br&gt;
Redux middleware allows developers to intercept and augment Redux actions before reaching the reducer, useful for handling asynchronous actions and side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;33. What is the significance of the useLayoutEffect Hook in React?&lt;/strong&gt;&lt;br&gt;
useLayoutEffect is similar to useEffect but fires synchronously after all DOM mutations, making it suitable for tasks requiring accurate measurements or DOM layout manipulation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;34. How does React handle errors in components?&lt;/strong&gt;&lt;br&gt;
React handles errors using error boundaries, special components that catch JavaScript errors in their child component tree and log them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;35. Explain the concept of the key prop in React lists.&lt;/strong&gt;&lt;br&gt;
The key prop provides a unique identifier to elements in React lists, optimizing updates by helping identify changes, additions, or removals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;36. What is the purpose of the useCallback Hook in React?&lt;/strong&gt;&lt;br&gt;
The useCallback Hook memoizes a callback function, preventing unnecessary re-creation and optimizing performance when dependencies don't change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;37. How does React handle conditional rendering?&lt;/strong&gt;&lt;br&gt;
Conditional rendering in React is achieved through conditional statements or ternary operators in JSX, allowing components to render different content based on specified conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;38. What is the role of the displayName property in React?&lt;/strong&gt;&lt;br&gt;
displayName is an optional property in React that provides a human-readable display name for components, aiding in debugging and making component hierarchies more understandable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;39. Explain the concept of hooks rules in React.&lt;/strong&gt;&lt;br&gt;
Hooks rules include calling them only in functional components and custom Hooks, ensuring consistent order across renders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;40. What is the significance of the useImperativeHandle Hook?&lt;/strong&gt;&lt;br&gt;
useImperativeHandle customizes the instance value exposed when using React.forwardRef, allowing more control over the child component's API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;41. What is the purpose of the contextType property in class components?&lt;/strong&gt;&lt;br&gt;
contextType in class components is used to consume context, providing access to the nearest current value of the context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;42. Explain the concept of lazy loading in React.&lt;/strong&gt;&lt;br&gt;
Lazy loading in React involves dynamically loading components or assets only when needed, improving performance by reducing initial page load time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;43. What is the significance of the useEffect cleanup function?&lt;/strong&gt;&lt;br&gt;
The useEffect cleanup function performs tasks like clearing intervals or unsubscribing when a component is unmounted or dependencies change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;44. How does React handle state in class components compared to functional components?&lt;/strong&gt;&lt;br&gt;
In class components, state is managed using this.state and this.setState(); in functional components, the useState Hook is used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;45. What is the role of the React.memo function in functional components?&lt;/strong&gt;&lt;br&gt;
React.memo is a higher-order component that memoizes a functional component, preventing unnecessary re-renders when props remain unchanged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;46. Explain the purpose of the useEffect dependency array.&lt;/strong&gt;&lt;br&gt;
The useEffect dependency array specifies dependencies that, when changed, trigger the effect to run, controlling when the effect should re-execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;47. What is the significance of the useRef Hook in React?&lt;/strong&gt;&lt;br&gt;
The useRef Hook creates mutable object references that persist across renders, often used for accessing and interacting with DOM elements imperatively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;48. How does React handle forms in controlled components?&lt;/strong&gt;&lt;br&gt;
React handles forms in controlled components by linking form elements to React state, enabling control and management of the form's data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;49. What is the purpose of the React.PureComponent class in React?&lt;/strong&gt;&lt;br&gt;
React.PureComponent is a base class that optimizes rendering performance by implementing a shallow prop and state comparison in shouldComponentUpdate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;50. Explain the concept of hooks in React.&lt;/strong&gt;&lt;br&gt;
Hooks in React are functions enabling state and other React features in functional components, allowing local component state and side effects.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Exploring MPC Wallets: Enhancing Blockchain Security and Privacy</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Sun, 06 Aug 2023 03:54:29 +0000</pubDate>
      <link>https://dev.to/shahbaz17/exploring-mpc-wallets-enhancing-blockchain-security-and-privacy-gk7</link>
      <guid>https://dev.to/shahbaz17/exploring-mpc-wallets-enhancing-blockchain-security-and-privacy-gk7</guid>
      <description>&lt;p&gt;In the world of blockchain and cryptocurrencies, security and privacy are of utmost importance. As technology advances, innovative solutions are emerging to address these concerns. One such solution that is gaining popularity is the Multi-Party Computation (MPC) wallet. This article will explain what MPC wallets are, how they function, how they differ from smart contract wallets, and the significance of MPC in blockchain technology. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is an MPC wallet?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An [MPC wallet](&lt;a href="https://web3auth.io/mpc"&gt;https://web3auth.io/mpc&lt;/a&gt;] is a cryptographic technique that is designed to enhance the security and privacy of digital assets stored in a blockchain. Unlike traditional single-key wallets, where a single private key grants access to funds, MPC wallets distribute control over private keys among multiple parties. This collaborative approach prevents any single entity from having complete access, reducing the risk of unauthorized access or malicious attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does an MPC wallet work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MPC wallets leverage mathematical computations and cryptography to achieve enhanced security. Multiple participants each contribute a part of the private key without revealing their components. These partial keys are then combined through complex algorithms to generate the complete private key only when needed for transactions. This ensures that no single participant possesses the full key at any point, significantly reducing the vulnerability of the wallet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between an MPC wallet and a smart contract wallet?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although both MPC wallets and smart contract wallets contribute to the security of digital assets, they differ in their underlying mechanisms. An MPC wallet relies on cryptographic protocols and mathematical calculations to ensure the safety of private keys. On the other hand, a smart contract wallet operates within the confines of a blockchain's scripting capabilities. It executes predefined rules and conditions, often governed by a smart contract, to manage funds. MPC wallets prioritize privacy and security through collaboration, whereas smart contract wallets emphasize automation and predetermined rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does MPC stand for in the context of blockchain?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the realm of blockchain, "MPC" stands for Multi-Party Computation. This term refers to a cryptographic technique that enables multiple parties to compute a function while keeping their inputs private jointly. This technique has far-reaching applications beyond wallets, including secure data sharing, privacy-preserving computations, and more. In the context of blockchain, MPC technology offers a groundbreaking way to manage private keys and enhance the overall security posture of the ecosystem.&lt;/p&gt;

&lt;p&gt;In conclusion, the emergence of MPC wallets represents a significant advancement in blockchain security. By distributing the control over private keys among multiple participants and utilizing complex cryptographic processes, MPC wallets minimize the risks associated with single points of failure. As the digital landscape continues to evolve, solutions like MPC wallets contribute to a more secure and privacy-focused blockchain ecosystem.&lt;/p&gt;

&lt;p&gt;To explore further and integrate enhanced security measures for your digital assets, consider adopting an [MPC wallet](&lt;a href="https://web3auth.io/mpc"&gt;https://web3auth.io/mpc&lt;/a&gt;]. The future of blockchain security lies in collaborative technologies that empower users to take control of their assets without compromising their privacy.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>A Comprehensive Guide to Deep links and App Links in Android</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Thu, 03 Aug 2023 07:59:21 +0000</pubDate>
      <link>https://dev.to/shahbaz17/a-comprehensive-guide-to-deep-links-and-app-links-in-android-4n23</link>
      <guid>https://dev.to/shahbaz17/a-comprehensive-guide-to-deep-links-and-app-links-in-android-4n23</guid>
      <description>&lt;p&gt;For Android developers, understanding the concepts of Deep links and App Links is crucial to providing a seamless user experience for end users. This guide delves into the differences between Deep links and App Links, importance of the security concerns, and how to implement and test these links effectively. &lt;/p&gt;

&lt;p&gt;Whether you're a developer integrating Web3Auth’s Android SDK or working with ReactNative/Flutter, this guide will help you master the art of handling links easily in your Android applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Deep Links and App Links
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What are Deep Links?
&lt;/h3&gt;

&lt;p&gt;To start, let's define what Deep Links are. Deep Links are strings of characters that enable users to access specific content or features within an Android app. They consist of three essential components: scheme, authority, and path. These links can handle custom schemes or universal resource identifiers (URIs) for seamless navigation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qqodC187--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6xlh8dziers3emmai42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qqodC187--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6xlh8dziers3emmai42.png" alt="DeepLink" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What are App Links?
&lt;/h3&gt;

&lt;p&gt;App Links are a specialized form of Deep Links that allow Android apps to handle HTTP and HTTPS web links. With App Links, developers can associate their app with specific web domains, providing users with a seamless experience when navigating between websites and the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Difference Between Android App Links and Web Links:
&lt;/h3&gt;

&lt;p&gt;While Android App Links and Web Links share similarities in their functionality as methods to link users to specific content, they have fundamental differences that cater to different user scenarios. Understanding these distinctions will help developers make informed decisions about which link type to use in various situations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Android App Links:
&lt;/h4&gt;

&lt;p&gt;Android App Links are a specialized form of Deep Links that offer a more seamless and integrated user experience for Android users. When a user clicks on an Android App Link, it automatically opens the associated app if it is installed on the device. This behavior eliminates the need for a disambiguation dialog that asks users to choose between opening the link in the app or the browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Characteristics of Android App Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Immediate App Invocation: Android App Links directly invoke the app, providing users with a faster and smoother experience as they are taken directly to the relevant content within the app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verified Association: Android App Links are explicitly associated with a specific app through a verification process, which ensures that only the designated app can handle these links. This verification is achieved through the use of Digital Asset Links JSON files hosted on the website's domain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Disambiguation Dialog: The absence of a disambiguation dialog streamlines the user journey and reduces the risk of users inadvertently choosing the wrong app to handle the link.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Web Links:
&lt;/h4&gt;

&lt;p&gt;On the other hand, Web Links are links that use the HTTP and HTTPS schemes and open in the device's default web browser. They are more generic and platform-agnostic, providing a consistent experience across different operating systems and devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Characteristics of Web Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Universal Accessibility: Web Links are accessible to all users, regardless of whether they have the app installed on their device. When users click on a Web Link, it opens the associated web page in the browser, making it a useful method for sharing content with a broader audience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not App-Specific: Unlike Android App Links, Web Links do not require any specific app association or verification. They can be used universally and do not rely on a particular app's presence on the device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Potential Disambiguation: Since Web Links are not bound to a specific app, users may have multiple apps that can handle a particular link. A disambiguation dialog may appear in such cases, prompting users to select the desired app for link handling.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Ensuring App Link Handling in Your Android App
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://web3auth.io/docs/content-hub/blog/comprehensive-guide-to-deep-links-and-app-links-in-android"&gt;Continue reading it here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>android</category>
      <category>security</category>
      <category>web3</category>
      <category>deeplink</category>
    </item>
    <item>
      <title>OAuth 2.0 and OpenID Connect Explained: Building Secure Authentication Systems</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Mon, 04 Jul 2022 05:13:31 +0000</pubDate>
      <link>https://dev.to/shahbaz17/oauth-20-openid-connect-41d</link>
      <guid>https://dev.to/shahbaz17/oauth-20-openid-connect-41d</guid>
      <description>&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1543917235181604864-66" src="https://platform.twitter.com/embed/Tweet.html?id=1543917235181604864"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1543917235181604864-66');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1543917235181604864&amp;amp;theme=dark"
  }



&lt;/p&gt;




&lt;p&gt;OAuth 2.0 and OpenID Connect (OIDC) are two essential protocols in web development, yet they often need to be understood and applied. This guide will delve into the intricacies of OAuth 2.0 and OIDC, clarify their roles, terminologies, and implementation flows, and shed light on how they work together to provide secure authentication and authorization mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding OAuth 2.0
&lt;/h2&gt;

&lt;p&gt;OAuth 2.0 is frequently misconceived as a protocol solely for authentication when, in fact, it primarily deals with authorization. At its core, OAuth 2.0 is an open standard designed for delegated authorization, allowing third-party applications to access restricted resources on behalf of a user with their consent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Roles in OAuth 2.0
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resource Owner&lt;/strong&gt;: The entity capable of granting access to a protected resource.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client&lt;/strong&gt;: The application makes requests for protected resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization Server&lt;/strong&gt;: This server is responsible for issuing access tokens after authenticating the resource owner and obtaining authorization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Server&lt;/strong&gt;: Hosts the protected resources that the client seeks to access.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key OAuth 2.0 Terminologies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access Token&lt;/strong&gt;: Credentials granted to the client by the authorization server, allowing access to protected resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope&lt;/strong&gt;: Specifies the extent of access granted to the client by the resource owner, which is crucial for defining the access boundaries in OAuth 2.0.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Authorization Grant
&lt;/h4&gt;

&lt;p&gt;An authorization grant is a credential representing the resource owner's consent for the client to access protected resources. There are different types of authorization grants, but two primary ones are worth noting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authorization Code Flow Grant&lt;/strong&gt;: In this flow, the client obtains an authorization code from the authorization server, which it then exchanges for an access token via a backend server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7iu1jrrvvcsyypiwfke2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7iu1jrrvvcsyypiwfke2.png" alt="OAuth2.0 Authorization code Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Implicit Flow Grant&lt;/strong&gt;: In the implicit flow, the client, often a single-page application (SPA), receives the access token from the authorization server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8jfvd4lpvrqnypegar17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8jfvd4lpvrqnypegar17.png" alt="OAuth2.0 Implicit Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing OpenID Connect (OIDC)
&lt;/h2&gt;

&lt;p&gt;While OAuth 2.0 provides a framework for authorization, it lacks specific guidelines for authentication. This is where OpenID Connect comes into play. OIDC serves as an identity layer built on OAuth 2.0, facilitating user authentication through the authorization server.&lt;/p&gt;

&lt;h3&gt;
  
  
  OIDC Terminology
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ID Token&lt;/strong&gt;: A token containing a set of personal attributes about a user, typically presented as a JWT.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  OIDC Implementation Flows
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Implicit Flow&lt;/strong&gt;: The SPA obtains the ID Token from the authorization server in this flow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4laowq81zei5twhcrlgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4laowq81zei5twhcrlgs.png" alt="OpenID Connect Implicit Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authorization Code Flow&lt;/strong&gt;: This flow is preferred for its enhanced security. It involves the client obtaining the ID Token via a backend server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lbgpfihx0xtw6nlfero.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lbgpfihx0xtw6nlfero.png" alt="OpenID Connect Authorization code Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By leveraging OIDC, developers can authenticate users securely while benefiting from the robust authorization mechanisms provided by OAuth 2.0.&lt;/p&gt;

&lt;p&gt;In conclusion, understanding the nuances of OAuth 2.0 and OpenID Connect is pivotal for implementing secure and efficient authentication and authorization processes in modern web applications. By grasping the roles, terminologies, and implementation flows outlined in this guide, developers can navigate these protocols effectively, ensuring user data protection and their applications' integrity.&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>oidc</category>
      <category>authentication</category>
      <category>authorization</category>
    </item>
    <item>
      <title>Demystifying Login with Ethereum</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Tue, 24 May 2022 13:09:00 +0000</pubDate>
      <link>https://dev.to/shahbaz17/demystifying-login-with-ethereum-55dg</link>
      <guid>https://dev.to/shahbaz17/demystifying-login-with-ethereum-55dg</guid>
      <description>&lt;p&gt;Geth is an Ethereum client written in Go. This means running Geth turns a computer into an Ethereum node. Ethereum is a peer-to-peer network where information is shared directly between nodes rather than being managed by a central server. Nodes compete to generate new blocks of transactions to send to its peers because they are rewarded for doing so in Ethereum’s native token, ether (ETH). On receiving a new block, each node checks that it is valid and adds it to their database. The sequence of discrete blocks is called a “blockchain”. The information provided in each block is used by Geth to update its “state” - the ether balance of each account on Ethereum. There are two types of account: externally-owned accounts (EOAs) and contract accounts. Contract accounts execute contract code when they receive transactions. EOAs are accounts that users manage locally in order to sign and submit transactions. Each EOA is a public-private key pair, where the public key is used to derive a unique address for the user and the private key is used to protect the account and securely sign messages. Therefore, in order to use Ethereum, it is first necessary to generate an EOA (hereafter, “account”). This tutorial will guide the user through creating an account, funding it with ether and sending some to another address.&lt;/p&gt;

&lt;p&gt;Read more about Ethereum accounts &lt;a href="https://ethereum.org/en/developers/docs/accounts/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Geth
&lt;/h1&gt;

&lt;p&gt;There are several ways to install Geth, including via a package manager, downloading a pre-built bundle, running as a docker container or building from downloaded source code.&lt;/p&gt;

&lt;p&gt;The easiest way to install go-ethereum on MacOS is to use the Geth Homebrew tap. The first step is to check that Homebrew is installed. The following command should return a version number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a version number is returned, then Homebrew is installed. If not, Homebrew can be installed by following the instructions here. With Homebrew installed, the following commands add the Geth tap and install Geth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap ethereum/ethereum
brew &lt;span class="nb"&gt;install &lt;/span&gt;ethereum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will installs the latest stable release.&lt;/p&gt;

&lt;p&gt;Check whether geth is installed or not by running the below command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;geth &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should output &lt;a href="https://geth.ethereum.org/docs/interface/command-line-options" rel="noopener noreferrer"&gt;command-line options&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Start Geth over HTTP Server
&lt;/h2&gt;

&lt;p&gt;Run the below command to start Geth over HTTP, enables access from any origin and exposes it's api's.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;geth &lt;span class="nt"&gt;--http&lt;/span&gt; &lt;span class="nt"&gt;--http&lt;/span&gt;.corsdomain &lt;span class="s2"&gt;"*"&lt;/span&gt; &lt;span class="nt"&gt;--http&lt;/span&gt;.api personal,eth,web3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--http&lt;/code&gt; flag enables the HTTP server.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--http.corsdomain "*"&lt;/code&gt; enables access from any origin.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--http.api personal,eth,web3&lt;/code&gt; enable access to APIs like "personal" which is by default not whitelisted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Create a Node JS application to interact with Geth[ETH]
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install Web3.js
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;web3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file and paste the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;web3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8545&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;web3Provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;web3Provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;msg_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a Secret Message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!@supersecret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// In real world app, this will be replaced with the private key.&lt;/span&gt;

&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pub_address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ETH Public Address: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
  &lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Signature: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ecRecover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recover_public_address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Recovered ETH Public Address: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recover_public_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recover_public_address&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Matched&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// Access allowed&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain, what's going on here.&lt;/p&gt;

&lt;p&gt;These lines are making a connecting between ETH blockchain (Geth running locally) and Web3.js library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;web3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8545&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;web3Provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;web3Provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the msg we want to sign using secret/private key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;msg_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a Secret Message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!@supersecret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are calling &lt;code&gt;personal.getAccount()&lt;/code&gt; to get an ETH public address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pub_address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ETH Public Address: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are updating the msg to include the ETH public address, so that later when we ecRecover the signature to get the public address, we can check the &lt;code&gt;ETH public address&lt;/code&gt; in the message with the retrieved public address from &lt;code&gt;ecRecover()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the following lines, we are signing the message(msg, that also includes the user's eth public address) using user's ETH public address, and secret/private key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Signature: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code will return a signature, that looks like:&lt;br&gt;
&lt;code&gt;0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The above &lt;code&gt;signature&lt;/code&gt; is passed to &lt;code&gt;ecRecover&lt;/code&gt; along with the original message returing the public address used to sign the message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ecRecover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recover_public_address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Recovered ETH Public Address: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recover_public_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the recovered_public_address is same as the public_address received in the message, it is fair to assure, the user has signed the message and access may be granted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recover_public_address&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pub_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Matched&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An Auth flow using ETH.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8v2zzr3yi2c8pkvf0ftb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8v2zzr3yi2c8pkvf0ftb.png" alt="An Auth flow using ETH."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All this is possible because of the Elliptic Curve Digital Signature Algorithm, or ECDSA.&lt;/p&gt;
&lt;h3&gt;
  
  
  Importance of Cryptographic signatures in Blockchain
&lt;/h3&gt;

&lt;p&gt;Cryptographic signatures are a key part of the blockchain. They are used to prove ownership of an address without exposing its private key.&lt;/p&gt;

&lt;p&gt;This is based on mathematical formulas. We take an input message, a private key and a (usually) random secret, and we get a number as output, which is the signature. Using another mathematical formula, this process can be reversed in such a way that the private key and random secret are unknown but can be verified.&lt;/p&gt;

&lt;p&gt;Ethereum SECP256k1 elliptic curve.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvic97dmctid12gn7isn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvic97dmctid12gn7isn.png" alt="Ethereum SECP256k1 elliptic curve."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication" rel="noopener noreferrer"&gt;elliptic curve point manipulation&lt;/a&gt;, we can derive a value from the private key, which is not reversible. This way we can create signatures that are safe and tamperproof. The functions that derive the values are called “trapdoor functions”:&lt;/p&gt;
&lt;h1&gt;
  
  
  Possible Attack
&lt;/h1&gt;

&lt;p&gt;For example, if &lt;code&gt;user A&lt;/code&gt; signs a message(M) and sends the signature(S), &lt;code&gt;user B&lt;/code&gt; can copy that signed message[S(M)] and original msg and send it to gain access.&lt;/p&gt;

&lt;p&gt;And using our current example code, since the msg includes the public address used to receive the signature. When using ecRecover with the signature and msg(containing public address), it will give back the eth address allowing access to the resource.&lt;/p&gt;
&lt;h1&gt;
  
  
  Possible Solution,
&lt;/h1&gt;

&lt;p&gt;How about adding challenge to the msg or encoding the msg to get a JWT token, using another set of secret? These's a lot of possible solution to add challenge at this step to identify the original user and authenticate securely.&lt;/p&gt;
&lt;h1&gt;
  
  
  Web3.js Functions
&lt;/h1&gt;
&lt;h2&gt;
  
  
  newAccount
&lt;/h2&gt;

&lt;p&gt;Creates a new account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Never call this function over a unsecured Websocket or HTTP provider, as your password will be sent in plain text!&lt;/p&gt;

&lt;p&gt;Read more &lt;a href="https://web3js.readthedocs.io/en/v1.2.11/web3-eth-personal.html?highlight=web3.eth.sign#newaccount" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!@superpassword&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0x1234567891011121314151617181920212223456&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  sign
&lt;/h2&gt;

&lt;p&gt;The sign method calculates an Ethereum specific signature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataToSign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read more &lt;a href="https://web3js.readthedocs.io/en/v1.2.11/web3-eth-personal.html?highlight=web3.eth.sign#sign" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test password!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ecRecover
&lt;/h2&gt;

&lt;p&gt;Recovers the account that signed the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ecRecover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataThatWasSigned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read more &lt;a href="https://web3js.readthedocs.io/en/v1.2.11/web3-eth-personal.html?highlight=web3.eth.sign#ecrecover" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;personal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ecRecover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though this approach to authenticate a user using blockchain is way secure than the centralised authentication where private key 🔑 sits in the centralised server. Any breach to centralized server will expose the user's private key.&lt;/p&gt;

&lt;p&gt;The approch used in this guide is &lt;code&gt;self-custodial&lt;/code&gt;, here, user's are responsible of keeping the secret/private key secure. Which again is a flawed system, user's are prone to attacks too and lossing the private key will be loosing the digital identity and assets.&lt;/p&gt;

&lt;p&gt;There's a better approach, that is non-custodial and uses Multi Party Computation. MPC enables multiple parties – each holding their own private data – to evaluate a computation without ever revealing any of the private data held by each party (or any otherwise related secret information).&lt;/p&gt;

&lt;p&gt;In my next post, I will talk about how different companies are protecting your Private Key and how's future looks like for true Self-Sovereign Identity without any compromises.&lt;/p&gt;

</description>
      <category>eth</category>
      <category>authentication</category>
      <category>programming</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Add MFA support easily with Magic</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Tue, 16 Nov 2021 15:00:43 +0000</pubDate>
      <link>https://dev.to/shahbaz17/add-mfa-support-easily-with-magic-p6c</link>
      <guid>https://dev.to/shahbaz17/add-mfa-support-easily-with-magic-p6c</guid>
      <description>&lt;p&gt;Multi-Factor Authentication (MFA) is an important part of a secure authentication process, but it's painful for developers to set it up correctly.&lt;/p&gt;

&lt;p&gt;In this post, I will walk you through to setup MFA in a sample application to add extra level of security.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pre-requisites
&lt;/h1&gt;

&lt;p&gt;All you need to get started is a &lt;a href="https://magic.link"&gt;Magic&lt;/a&gt; account.&lt;/p&gt;

&lt;p&gt;New to Magic? &lt;a href="https://dashboard.magic.link/signup"&gt;Sign up for free&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Set up
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Add the login form script
&lt;/h2&gt;

&lt;p&gt;Create a new login page &lt;code&gt;index.html&lt;/code&gt; and add the script tag below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Start the login flow just by including this script tag! --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://auth.magic.link/pnp/login"&lt;/span&gt;
    &lt;span class="na"&gt;data-magic-publishable-api-key=&lt;/span&gt;&lt;span class="s"&gt;"pk_live_7F4F8AEF74A0C9BC"&lt;/span&gt;
    &lt;span class="na"&gt;data-redirect-uri=&lt;/span&gt;&lt;span class="s"&gt;"/callback.html"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your API key can be found on the Home page of your &lt;a href="https://dashboard.magic.link/signup"&gt;Magic Dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jNafUo0s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k779bi7ezxydhp1tea8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jNafUo0s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k779bi7ezxydhp1tea8k.png" alt="Magic Dashboard" width="880" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will generate a pre-built login form based on the branding and login methods you’ve enabled via Dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pojc7or2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vt33xp0pp24ixo1ykt4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pojc7or2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vt33xp0pp24ixo1ykt4.png" alt="Magic Login" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add the callback script
&lt;/h2&gt;

&lt;p&gt;Next, create a &lt;code&gt;callback.html&lt;/code&gt; page containing the script tag below to handle the authentication callback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Automatically handle auth callback using Magic! --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://auth.magic.link/pnp/callback"&lt;/span&gt;
    &lt;span class="na"&gt;data-magic-publishable-api-key=&lt;/span&gt;&lt;span class="s"&gt;"pk_live_7F4F8AEF74A0C9BC"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Use data from Magic! --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@magic/ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userMetadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oauth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/css/main.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- UI implementation --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"page"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Now let's enable MFA&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/settings.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open user settings&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; to enable
      MFA.
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Once enabled, &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/logout.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;log out&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; then log
      back in to try multi-factor login.
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon a user's successful login, you may wish to perform your own client-side and server-side business logic. To do so, you can hook into the &lt;code&gt;@magic/ready&lt;/code&gt; event on the &lt;code&gt;window&lt;/code&gt; object of the page containing your &lt;code&gt;https://auth.magic.link/pnp/callback&lt;/code&gt; script.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@magic/ready&lt;/code&gt; event contains an object of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events#adding_custom_data_%E2%80%93_customevent"&gt;custom data attached&lt;/a&gt; to &lt;code&gt;event.detail&lt;/code&gt;. The following fields are surfaced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;magic&lt;/code&gt; - An instance of &lt;a href="https://magic.link/docs/api-reference/client-side-sdks/web"&gt;Magic JS&lt;/a&gt; which can be used to interface with any Magic methods at a low-level.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;idToken&lt;/code&gt; - A &lt;a href="https://magic.link/docs/introduction/decentralized-id"&gt;DID token&lt;/a&gt; for the user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;userMetadata&lt;/code&gt; - Up-to-date &lt;a href="https://magic.link/docs/api-reference/client-side-sdks/web#getmetadata"&gt;user metadata&lt;/a&gt; for the user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;oauth&lt;/code&gt; - An &lt;a href="https://magic.link/docs/login-methods/social-logins/oauth-implementation/web"&gt;OAuth response&lt;/a&gt; for the user, if the login method was initiated through an OAuth provider — otherwise, this field is &lt;code&gt;undefined&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add the logout script
&lt;/h2&gt;

&lt;p&gt;Now, create a &lt;code&gt;logout.html&lt;/code&gt; page containing the script tag below to handle the logout function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Automatically handle logout using Magic! --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://auth.magic.link/pnp/logout"&lt;/span&gt;
    &lt;span class="na"&gt;data-magic-publishable-api-key=&lt;/span&gt;&lt;span class="s"&gt;"pk_live_7F4F8AEF74A0C9BC"&lt;/span&gt;
    &lt;span class="na"&gt;data-redirect-uri=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementing User Settings for MFA
&lt;/h2&gt;

&lt;p&gt;Magic provides an out-of-the-box settings widget through which your users can self-service different functions of their account, including enabling or disabling &lt;a href="https://magic.link/docs/login-methods/mfa"&gt;multi-factor auth (MFA)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, create a &lt;code&gt;settings.html&lt;/code&gt; page containing the script tag below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Automatically handle logout using Magic! --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://auth.magic.link/pnp/settings"&lt;/span&gt;
    &lt;span class="na"&gt;data-magic-publishable-api-key=&lt;/span&gt;&lt;span class="s"&gt;"pk_live_7F4F8AEF74A0C9BC"&lt;/span&gt;
    &lt;span class="na"&gt;data-redirect-uri=&lt;/span&gt;&lt;span class="s"&gt;"/callback.html"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users will automatically be redirected to the URI provided in &lt;code&gt;data-redirect-uri&lt;/code&gt; (or, if no value is provided, a relative path of &lt;code&gt;/callback&lt;/code&gt;) upon dismissal of the settings widget. In your custom callback logic, you will have access to a &lt;code&gt;prevUserMetadata&lt;/code&gt; field on the &lt;code&gt;@magic/ready&lt;/code&gt; event data so that settings updates can be manually diffed and utilized in your app. If a user is not currently logged-in upon accessing the settings widget, they will be automatically redirected to the URI provided in &lt;code&gt;data-login-uri&lt;/code&gt; (or, if no value is provided, &lt;code&gt;window.location.origin&lt;/code&gt; is used instead).&lt;/p&gt;

&lt;h2&gt;
  
  
  Add some CSS to look nice
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;css/main.css&lt;/code&gt; file and paste the below code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.page&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.data&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:first-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.data&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Roboto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.data&lt;/span&gt; &lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;gainsboro&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#18171a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Inter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;28px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;368px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#6851ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enable MFA in Dashboard
&lt;/h2&gt;

&lt;p&gt;Enable through Multi-factor Auth Dashboard page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6GK9doxZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3sbmzdf63djwiczg61a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6GK9doxZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3sbmzdf63djwiczg61a.png" alt="Multi-factor Auth Dashboard page" width="880" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  User's 1st login flow after MFA is configured
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gHFbyp2c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzqbo9ls1qet4diq9jj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gHFbyp2c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzqbo9ls1qet4diq9jj8.png" alt="Email Login with Magic" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's time to check MFA in our application. The home page(&lt;a href="https://lmr9z.csb.app"&gt;https://lmr9z.csb.app&lt;/a&gt;) would look something like above 👆, with Email and SMS login option enabled. You can enable Social login options too, but MFA is currently supported for email and SMS primary factors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Un4Ybfgu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/973xrnbglcyfmjp49qiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Un4Ybfgu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/973xrnbglcyfmjp49qiz.png" alt="Check email" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon providing your email and clicking &lt;code&gt;Log in / Sign up&lt;/code&gt; button, you will see a pop-up window saying "Check your email".&lt;/p&gt;

&lt;p&gt;Note: Don't close this tab, Check your email and click the link to log in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fZk9I2ge--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5v5vl6bf52hel91z7ue2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fZk9I2ge--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5v5vl6bf52hel91z7ue2.png" alt="Don't close this tab" width="880" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon successful login, you'll be redirected to callback page. Here, we will enable MFA. Once enabled, upon next login, MFA flow will be used.&lt;/p&gt;

&lt;p&gt;Let's open the user's settings page by clicking &lt;code&gt;Open user settings&lt;/code&gt; link on the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MmEWP6ca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hvzlhwh1fuhpwrxoytp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MmEWP6ca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hvzlhwh1fuhpwrxoytp.png" alt="Callback page after successful login" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, you'll see the 2-step verification as &lt;code&gt;OFF&lt;/code&gt;.&lt;br&gt;
Click on &lt;code&gt;Turn on&lt;/code&gt; button to enable it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eoh5EUb1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ek2l3opf560glt9mbv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eoh5EUb1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ek2l3opf560glt9mbv5.png" alt="Open user's setting page" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll need to choose an authenticator app like &lt;strong&gt;Google Authenticator&lt;/strong&gt; or &lt;strong&gt;Authy&lt;/strong&gt; to enable two-step verification.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GVjNpDPm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14lssl5f208d9qj3asfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GVjNpDPm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14lssl5f208d9qj3asfw.png" alt="Select Google or Authy" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, scan the QR code displayed with your authenticator app and click on the &lt;code&gt;Next&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lm4XGqtq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nsg96sgrdvo69d5f9470.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lm4XGqtq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nsg96sgrdvo69d5f9470.png" alt="Scan this QR code" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this step, please enter the 6-digit code from your authenticator app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2P4cmb0B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygh87p4xqp1pmdakrpub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2P4cmb0B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygh87p4xqp1pmdakrpub.png" alt="Enter 6 digit code from Authenticator app" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon success, you'll be prompted to save your recovery code. Store this in a safe place. This code can be used to log in if you lose access to your authenticator app. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YENhhLek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8njr9agj9p546i2bn1ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YENhhLek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8njr9agj9p546i2bn1ec.png" alt="Save your recovery code" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;code&gt;Finish setup&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---FzhxUbK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/je2q747g9g880nu3xm6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---FzhxUbK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/je2q747g9g880nu3xm6v.png" alt="2 step verification is complete" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2-step verification status is now &lt;code&gt;ON&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Logout and Log back in to see the MFA in action.&lt;/p&gt;

&lt;p&gt;In your next visit, upon clicking the link in your email, you'll be prompted to enter the 6-digit code from your authenticator app or the same recovery code you stored in some place safe.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gYRxnMot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhp4tspjk5l4rh7ndw9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gYRxnMot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhp4tspjk5l4rh7ndw9e.png" alt="MFA - Enter code" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---7bJwIvk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0dg5o4fjxnxwvpfr75j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---7bJwIvk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0dg5o4fjxnxwvpfr75j.png" alt="Enter Recovery code" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for this post, I hope to see your application using MFA. &lt;/p&gt;

&lt;p&gt;Here are some useful links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live Demo: &lt;a href="https://lmr9z.csb.app"&gt;https://lmr9z.csb.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code on GitHub: &lt;a href="https://github.com/magiclabs/example-mfa"&gt;https://github.com/magiclabs/example-mfa&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MFA: &lt;a href="https://magic.link/docs/login-methods/mfa"&gt;https://magic.link/docs/login-methods/mfa&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Magic: &lt;a href="https://magic.link"&gt;https://magic.link&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mfa</category>
      <category>auth</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Add Magic Login with just 2 script tags</title>
      <dc:creator>Mohammad Shahbaz Alam</dc:creator>
      <pubDate>Wed, 27 Oct 2021 16:35:12 +0000</pubDate>
      <link>https://dev.to/shahbaz17/add-magic-login-with-just-2-script-tags-3m7g</link>
      <guid>https://dev.to/shahbaz17/add-magic-login-with-just-2-script-tags-3m7g</guid>
      <description>&lt;p&gt;In this post, learn how to integrate Magic's custom, production-ready passwordless login to your website with just 2 script tags and a Magic account. &lt;/p&gt;

&lt;p&gt;New to &lt;a href="https://magic.link"&gt;Magic&lt;/a&gt;? &lt;a href="https://dashboard.magic.link/signup"&gt;Sign up for free&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently it only supports Web(JavaScript). Stay tuned for React Native, iOS and Android.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1 - Add login form script to login page.
&lt;/h1&gt;

&lt;p&gt;Create a new login page and add the script tag below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;
  &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://auth.magic.link/pnp/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;magic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;publishable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[YOUR_PUBLISHABLE_API_KEY_HERE]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/callback&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="nx"&gt;Replace&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your API key can be found on the Home page of your &lt;a href="https://dashboard.magic.link/signup"&gt;Magic Dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This will generate a pre-built login form based on the branding and login methods you’ve enabled via Dashboard. Users will automatically be redirected to the URI provided in &lt;code&gt;data-redirect-uri&lt;/code&gt; upon authorization. If no &lt;code&gt;data-redirect-uri&lt;/code&gt; is specified, a relative path — &lt;code&gt;/callback&lt;/code&gt; — is automatically used as a fallback.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2 - Add the callback script
&lt;/h1&gt;

&lt;p&gt;Next, create a page containing the script tag below to handle the authentication callback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;
  &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://auth.magic.link/pnp/callback&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;magic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;publishable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[YOUR_PUBLISHABLE_API_KEY_HERE]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Try it out!
&lt;/h1&gt;

&lt;p&gt;Open your login page to try out your new end-to-end Magic authentication flow.&lt;/p&gt;

&lt;h1&gt;
  
  
  Logging users out
&lt;/h1&gt;

&lt;p&gt;You can optionally provide an endpoint in your app to log users out of their Magic session. Users will automatically be redirected to the URI provided in &lt;code&gt;data-login-uri&lt;/code&gt; or &lt;code&gt;data-redirect-uri&lt;/code&gt; upon successful logout. If no &lt;code&gt;data-login-uri&lt;/code&gt; or &lt;code&gt;data-redirect-uri&lt;/code&gt; is specified, the current value of &lt;code&gt;window.location.origin&lt;/code&gt; is used instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;
  &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://auth.magic.link/pnp/logout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;magic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;publishable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[YOUR_PUBLISHABLE_API_KEY_HERE]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="nx"&gt;Replace&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To learn more about script options, customization and FAQs &lt;a href="https://magic.link/docs/login-form"&gt;read here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
