Decentralized Identity - Build A Profile With Next - JS, Ethereum & Ceramic Network
Decentralized Identity - Build A Profile With Next - JS, Ethereum & Ceramic Network
Idris Olubisi
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 1/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
Long-standing centralized intermediaries, like the government or big companies, are the
ones who make and keep your ID information in traditional systems that manage who you
are.
But this implies that you have no control over the information relating to your identification,
who has access to personally identifiable information (PII), and to what extent.
In this article, you will learn about Decentralized Identity, Decentralized Identifiers, Ceramic
network, and how to build a decentralized identity profile with Ethereum on Ceramic
Networks.
This is made possible by using decentralized technologies, such as blockchain. These give
people control and ownership over the information associated with their identities rather than
having it stored on a central server or managed by a third party.
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 2/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
Blockchain-based digital wallets, such as those used to store and handle cryptocurrencies,
serve as a practical illustration of decentralized identification. Users of these wallets control
the private keys that provide them access to their money and can distribute their public keys
to others to accept payments from them.
Users who manage their private keys can conduct transactions with others without relying on
a central authority, such as a bank, and keep custody of their money.
DIDs are a vital component of the developing decentralized identity ecosystem. They are
designed to offer a uniform process for developing, maintaining, and exchanging digital
identities unaffiliated with any one company or piece of technology.
This implies that a DID can be maintained and controlled by the person or entity to which it
belongs and utilized across various systems and applications.
In recent years, smart contract platforms like Ethereum have demonstrated the utility of
decentralized applications (dApps) that can be assembled like blocks to create new
applications. This is especially evident in tokens that build upon one another, in DeFi
protocols that use one another, and so on.
Thanks to Ceramic, data on the internet can now have the same kind of composability. Any
data type, including profiles, social connections, blog posts, identities, reputations, and so
on., can be included. You will learn more about Ceramic Network in the section below.
With the help of stream processing provided by Ceramic, developers can build apps that are
strong, safe, trustless, and censorship-resistant using dynamic information – without using
unreliable database servers.
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 3/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
Ceramic stores all content in smart documents, which are append-only IPFS logs. Before
being anchored in a blockchain for consensus, each commit is verified by a decentralized
identification (DID).
All papers in Ceramic are openly discoverable and can be referenced by other documents or
queried by any other network user because the system is entirely peer-to-peer.
Developers now have an easier time creating decentralized identification solutions that can
be integrated with other programs and systems.
Ceramic Network also provides a set of developer tools and libraries, making it simple to
create decentralized identity apps and services. These tools include SDKs, APIs, developer
guides, and an expanding ecosystem of open-source tools and libraries.
Now that you have learnt the theories behind decentralized identity, let's take a practical
deep dive and get your hands dirty.
Prerequisites
To go through this tutorial, you'll need some experience with JavaScript and React.js.
Experience with Next.js isn't a requirement, but it's nice to have.
Make sure to have Node.js or npm installed on your computer. If you don't, click here.
Also, it'll be very useful to have a basic understanding of blockchain technology and Web3
concepts.
Navigate to the terminal and cd into any directory of your choice. Then run the following
commands:
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 4/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
mkdir decentralized-identity-project
cd decentralized-identity-project
npx create-next-app@latest .
Install the @self.id/react and @self.id/web packages using the code snippet below:
You should have something similar to what is shown below: the default boilerplate layout for
Next.js 13.
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 5/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
In this section, you will set up Tailwind CSS in a Next.js project. Install tailwindcss and its
peer dependencies via npm, and then run the init command to generate both
tailwind.config.js and postcss.config.js.
Navigate to the tailwind.config.js file, and add the paths to your template files with the
following code snippet.
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
Delete all the CSS styles inside globals.css . Add the @tailwind directives for each of
Tailwind’s layers to your globals.css file.
@tailwind base;
@tailwind components;
@tailwind utilities;
The Provider component must be placed at the top of the application tree to use the hooks
detailed below. You can use it to supply an initial state as well as a specific configuration for
the Self.ID clients and queries.
Update the _app.js file under the pages folder with the following code snippet:
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 6/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
return (
<Provider client={{ ceramic: "testnet-clay" }}>
<Component {...pageProps} />
</Provider>
);
}
Imported a context provider component and global CSS styles and then defined an App
component that wraps the entire application with the context provider.
Configured the context provider with a Ceramic testnet client, which allows the
application to access authentication and authorization functionality.
Finally, the Component is rendered with its props inside the context provider, allowing
the application to access the authentication and authorization context.
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 7/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
return (
<>
<Head>
<title>
Decentralized Identity: Build a Profile with NextJs, Ethereum & Ceramic
Network
</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className="min-h-screen bg-gray-200">
<div className="bg-gray-600 py-4 px-4 sm:px-6 lg:px-8 lg:py-6 shadow-lg text-
white">
<div className="container mx-auto px-6 md:px-0">
<h1 className="text-2xl font-bold text-white text-center">
Decentralized Identity: Build a Profile with NextJs, Ethereum & Ceramic
Network
</h1>
</div>
</div>
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 8/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 9/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
</button>
</div>
</form>
</div>
</div>
</div>
</main>
</>
);
}
To start the application, run the following command and navigate to localhost:3000 on your
browser; you should have something similar to what is shown below:
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 10/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
//..
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 11/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
onClick={() => {
connectAccount();
}}
>
Connect Wallet
</button>
) : (
<p className="text-red-500 text-sm italic mt-2 text-center w-full">
An injected Ethereum provider such as{" "}
<a href="https://metamask.io/">MetaMask</a> is needed to
authenticate.
</p>
)}
</div>
</>
)
}
The useViewerConnection hook is used to set up a state variable for the user's
connection status, connect and disconnect.
isWindow to set the initial state of the the window to avoid React hydration error
The useViewerRecord hook is used to retrieve the user's basic profile data.
The createAuthProvider function creates an EthereumAuthProvider object using the
window.ethereum provider.
The connectAccount function calls createAuthProvider and connects to the user's
account using connect(authProvider).
The JSX code conditionally renders a button based on the user's connection status
and the availability of an ethereum provider in the window object.
If the user is already connected, the button will enable them to disconnect. If the user is
not yet connected and an ethereum provider is available, the button will enable them to
connect. But if the user is not connected and no ethereum provider is available, a
message will be displayed to inform the user that an injected Ethereum provider like
MetaMask is required to authenticate.
Testing out the authentication functionality, you should have something similar to what is
shown below:
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 12/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
pages/index.js
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 13/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
//...
//...
// Use the merge method to update the record with the new information
await record.merge({
name,
bio,
username,
});
}
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 14/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
<p className="mb-4">
<span className="font-bold text-gray-700 mr-2 text-lg">
Bio:
</span>{" "}
<span id="bioOutput" className="text-lg">
{record.content.bio || "No bio set"}
</span>
</p>
<p>
<span className="font-bold text-gray-700 mr-2 text-lg">
Username:
</span>{" "}
<span id="usernameOutput" className="text-lg">
{record.content.username || "No username set"}
</span>
</p>
</div>
</div>
) : (
<div className="mt-8">
<div className="bg-white p-8 rounded-lg shadow-lg">
<p>No profile found.</p>
</div>
</div>
)}
</div>
</div>
</>
)
}
The component uses the useState hook to manage the state of three variables: name,
bio, and username.
There's an async function called updateProfile that is responsible for merging the
current state of the variables into a record.
If any of the variables is empty, the updateProfile function returns without updating
the record.
There are three conditional statements that render a different UI based on whether a
record is found or not.
The first conditional statement checks whether the record is still loading, and if it is, it
displays a Loading... message.
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 15/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
The second conditional statement checks whether there's no record content and the
connection status is connected. If this is true, it displays a No profile found.
message.
The third conditional statement checks whether the record content exists. If it does, it
displays the profile information, which includes the user's name, bio, and username.
You are almost there. In the form tag, update the name, bio and username input field with the
following code:
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 16/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
<div className="mb-6">
<label
className="block text-gray-700 font-bold mb-2"
htmlFor="name"
>
Name
</label>
<input
//...
onChange={(e) => {
setName(e.target.value);
}}
/>
</div>
<div className="mb-6">
<label
className="block text-gray-700 font-bold mb-2"
htmlFor="bio"
>
Bio
</label>
<textarea
//...
onChange={(e) => {
setBio(e.target.value);
}}
></textarea>
</div>
<div className="mb-6">
<label
className="block text-gray-700 font-bold mb-2"
htmlFor="username"
>
Username
</label>
<input
//...
onChange={(e) => {
setUsername(e.target.value);
}}
/>
</div>
In the code snippet above, setName, setBio, and setUsername are functions provided by the
useState hook that update the state of name, bio, or username.
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 17/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
//...
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
type="submit"
disabled={!record.isMutable || record.isMutating}
onClick={() => updateProfile()}
>
{record.isMutating ? "Updating..." : "Update Profile"}
</button>
//..
In the code snippet above, the button is disabled when the record is not mutable or is
currently mutating.
When the button is clicked, it calls the updateProfile function, which is responsible for
updating the user's profile information. If the record mutates, the button will display
Updating.... Otherwise, it will display Update Profile.
You can test out the application similar to what is shown below.
https://www.loom.com/share/f2103bcb44c949f7bfdbd5cb531b0c71
Kindly find the complete code on GitHub repository here.
Conclusion
In this post, you learn about Decentralized Identity, Decentralized Identifiers, Ceramic
networks, why Ceramic network is useful, and how to build a decentralized identity profile
with Ethereum on Ceramic Networks.
References
Ceramic Network
Ceramic Documentation
Decentralized Identity - Ethereum
Idris Olubisi
Software Engineer | Developer Advocate | Technical Writer | Content Creator
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 18/19
12/1/24, 12:33 PM Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network
If you read this far, thank the author to show them you care.
Learn to code for free. freeCodeCamp's open source curriculum has helped more than
40,000 people get jobs as developers. Get started
https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/ 19/19